eventLoop

本文最后更新于:2023年8月15日 下午

宏任务和微任务

在 JS 的异步代码中又区分 “宏任务(MacroTask)” 和 “微任务(MicroTask)”

  • 宏任务:宏/大的意思,可以理解为比较 费时 比较  的任务
  • 微任务:微/小的意思,可以理解为相对没那么费时没那么慢的任务

常见的宏任务和微任务

  • MacroTask:setTimeout、setInterval、setImmediate(IE独有) …
  • MicroTask:Promise、MutationObserver、process、nextTick(node独有) …

注意点:所有的宏任务和微任务都会放到自己的执行队列中,也就是有一个 宏任务队列 和一个 微任务队列,所有放到队列中的任务都采用 **”先进先出原则”**,也就是多个任务同时满足条件,那么会先执行先放进去的

完整执行顺序

  1. 从上至下执行所有同步代码
  2. 执行微任务队列中所有任务
  3. 执行宏任务队列中的第一个
  4. 然后执行2,3,2,3如此往复直至结束

注意点:

  • 每次执行宏任务都是去一个出来
  • 每次执行微任务都是立刻清空
  • 在执行过程中遇到宏任务就放到宏任务队列中,遇到微任务就放到微任务队列中,这个操作在每一步都可能遇到
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function a() {
console.log('a');        
Promise.resolve().then(() => {          
console.log('e');        
});        
Promise.resolve().then(() => {          
console.log('ee');        
});    
}
function b() {console.log('b');}
function c() {
console.log('c');      
Promise.resolve().then(() => {        
console.log('cc');      
});    
}
function d() {        
setImmediate(a);        
var temp = Promise.resolve().then(b);        
setTimeout(c, 0);        
console.log('d');    
}    
d();// d b a e ee c cc

执行解析:

    1、遇到第一个setImmediate放入宏任务队列 【a】

    2、遇到promise 放入 微任务队列 【b】

    3、遇到第二个setTimeout放入宏任务队列 【a,c】

    4、输出:d,主js代码执行完毕

    5、读取微任务队列所有任务,输出 :b

    6、读取宏任务队列,取出第一个【a】,输出:a,同时放入微任务队列:【e,  ee】

    7、读取微任务队列所有任务,输出 :e    ee

    8、读取宏任务队列,取出第一个【c】,输出:c,同时放入微任务队列:【cc】

    9、读取微任务队列所有任务,输出 : cc

    10、执行完毕

参考:

https://www.jianshu.com/p/92f4506a28d0

https://www.jianshu.com/p/1486afd81594

https://www.cnblogs.com/BNTang/articles/15171676.html


eventLoop
http://bestkele.com/2020/07/19/concept/eventloop/
作者
kele
发布于
2020年7月19日
许可协议