当前位置: 首页 > news >正文

JavaScript的宏任务和微任务

宏任务和微任务

    • JS为微任务和宏任务简单介绍
      • 任务执行顺序例子
      • 任务执行顺序简单例子
    • 关于new Promise实例化过程的例子

JS为微任务和宏任务简单介绍

  1. js是单线程的,但是分同步异步
  2. 微任务和宏任务皆为异步任务,它们都属于一个队列
  3. 宏任务一般是:script、setTimeout、setInterval、postMessage
  4. 微任务:Promise.then ES6
  5. 先执行同步再执行异步,异步遇到微任务,先执行微任务,执行完后如果没有微任务,就执行下一个宏任务,如果有微任务,就按顺序一个一个执行微任务

任务执行顺序
同步任务 ——> 异步任务中微任务 ——> 异步任务中宏任务

任务执行顺序例子

function doFoo(fn) {this.code = 404;fn();
}function f() {setTimeout(() => {console.log(">>>" + this); // >>>[object window],语句3this.code = 401; // 语句4}, 0)console.log( this.code ); // 404,语句2
}let obj = {code: 200,foo: f
};var code = 500;doFoo( obj.foo ); // 语句1
setTimeout(()=>{console.log(obj.code)}, 0); // 200,语句5
setTimeout(()=>{console.log(window.code)}, 0); // 401,语句6

分析

  1. 按照先同步再异步的顺序,从上往下编译执行,第一个执行doF( obj.foo )任务,将obj.foo作为参数传入到函数doFoo当中,此时作为调用者的对象还是window,doFoo函数中this.code = 404;将window对象下的code值修改为404
  2. 之后doFoo函数继续调用 f() 函数,f()函数中的setTimeout()是宏任务,先放入宏任务列表里,不执行,反而直接执行后面的 console.log( this.code ); 此时调用该函数的对象还是window,所以打印出404,继续接下来的任务,将两个setTimeout()都放入宏任务列表
  3. 执行第一个放入的setTimeout()任务,执行其中this.code=401,将window对象下的code的值又修改为401
  4. 执行第二个放入的setTimeout()任务,执行console.log(obj.code),整个过程中obj对象的code一直没被修改,所以还是200
  5. 执行第三个放入的setTimeout()任务,执行console.log(window.code),打印出401

任务执行顺序简单例子

console.log(1)
setTimeout(function() {console.log(2)
}, 0)
const p = new Promise((resolve, reject) => {resolve(4)
})
p.then(data => {console.log(data)
})
console.log(3)
//1,3,4,2

分析

  1. 先同步再异步,从上往下编译执行,首先遇到同步任务console.log(1);输出1;
  2. 接着遇到setTimeout 异步宏任务,放入宏任务队列中;
  3. 接着遇到 Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,但由于new Promise没有输出事件,所以无事发生。
  4. 接着遇到.then,then是异步微任务,不执行,加入到异步微任务列表;
  5. 遇到同步任务console.log(3);输出3;
  6. 主线程中同步任务执行完,从微任务队列中取出任务到主线程中,先取出作为微任务的.then,p.then 输出4,微任务执行完毕,微任务队列为空;
  7. 开始执行宏任务setTimeout 输出2,宏任务队列为空;

重点注意new Promise在实例化的过程中所执行的代码都是同步进行的

关于new Promise实例化过程的例子

console.log(1)
setTimeout(function() {console.log(2)new Promise(function(resolve) {console.log(3)resolve()}).then(function() {console.log(4)})
})new Promise(function(resolve) {console.log(5)resolve()
}).then(function() {console.log(6)
})setTimeout(function() {console.log(7)new Promise(function(resolve) {console.log(8)resolve()}).then(function() {console.log(9)})
})
console.log(10)
//1,5,10,6,2,3,4,7,8,9

分析

  1. 先同步再异步,从上往下编译执行,首先遇到同步任务console.log(1);输出1;
  2. 遇到setTimeout 异步宏任务,放入宏任务队列中;
  3. 遇到 Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出5,
  4. 所以接着遇到.then;.then,异步微任务,被分发到微任务Event Queue中;
  5. 遇到setTimeout,异步宏任务;放入宏任务队列中;
  6. 遇到同步任务console.log(10);输出10,主线程中同步任务全部执行完;
  7. 同步任务全部执行完,从微任务队列中取出任务到主线程中,输出6;
  8. 在从宏任务队列中取出任务到主线程中,执行第一个setTimeout,输出2,3,4(在宏任务中执行同步,同步,异步微任务);
  9. 在执行第二个setTimeout,输出7,8,9(和8同理);
http://www.lryc.cn/news/103008.html

相关文章:

  • java的空引用null和空字符串““
  • Python+OpenCV实现自动扫雷,挑战扫雷世界记录!
  • XtarBackup 8.0.33-28 prepare 速度提升 20 倍!
  • Blazor前后端框架Known-V1.2.8
  • python模拟加密爬取诸葛
  • 安全学习DAY13_WEB应用源码获取
  • Selenium+Java环境搭建(测试系列6)
  • Shell编程学习-If条件语句
  • Android getDrawable()和getColor()
  • Android Calendar
  • C# PaddleDetection 目标检测 ( yolov3_darknet)
  • matlab多线程,parfor循环进度,matlab互斥锁
  • 建木使用进阶-创建密钥管理
  • 多模态第2篇:MMGCN代码配置
  • DHCP部署与安全详解
  • 华为数通HCIP-PIM原理与配置
  • linux 权限
  • SQL基础使用
  • 金蝶云星空任意文件读取漏洞复现(0day)
  • linux中readelf命令详解
  • Python 教程之标准库概览
  • MySQL~数据库的基本概念
  • uniapp文件下载
  • 让GPT人工智能变身常用工具-下
  • el-table 表格头部合并
  • 【机器学习】Linear Regression
  • STM32 中断优先级管理(二)
  • 17-汽水瓶
  • Mindar.JS——实现AR图像追踪插入图片或视频
  • JVM源码剖析之JIT工作流程