JavaScript 宏任务和微任务

宏任务和微任务

1. 异步任务分类:

  • 宏任务(macrotask):
    • 异步Ajax请求
    • setTimeout, setInterver
    • 文件操作
    • 其他宏任务
  • 微任务(microtask):
    • Promise
    • process.nextTick
    • 其他

2. 执行顺序(交替执行)

每一个宏任务执行完后,都会检查是否存在待执行的微任务;

如果有,则执行完所有微任务之后,再继续执行下一个宏任务。

微任务执行流程图

3. 去银行办业务的场景

  1. A和B去银行办业务。首先,需要取号之后进行排队
    • 宏任务队列;
  2. 假设当前银行网点只有一个柜员,A在办理存款业务时,B只能等待
    • 单线程,宏任务按次序执行;
  3. A办理完存款业务后,柜员询问他是否还想办理其他业务
    • 当前宏任务执行完,检查是否有微任务;
  4. A告诉柜员:想要买理财产品、办信用卡等。
    • 执行微任务,后续宏任务被推迟;
  5. A离开柜台后,柜员开始为B办理业务;
    • 所有微任务执行完毕,开始执行下一个宏任务;

4. 分析代码输出顺序

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

分析:

  1. 先执行所有同步任务:

    • 第6、12行
  2. 再执行微任务:

    • 第9行;
  3. 再执行下一个宏任务:

    • 第2行

5. 经典面试题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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);
})
})
// 156234789

同步任务:1 5

  • 微任务:6

宏任务:2 3

  • 微任务:4

宏任务:7 8

  • 任务:9