https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ 这个网站可以帮助理解,下面是我的笔记
注意:新的w3c规范已经撤销了宏任务的说法,代替它的是多种任务队列,但是为了解释方便,下面依然使用宏任务,代替这些乱七八糟的任务队列。
微任务
(MutationObserver,Promise)的执行优先级是最高的。户交互任务,宏任务的一种
(点击等事件)。定时器任务,宏任务的一种
(setTimeout,setInterval)。渲染主线程从微队列中拿任务是一个一个拿,还是一次性都拿出来,目前还没找到可靠的说法,但是无论是哪一种机制,执行结果都是相同的,所以这点不用过分纠结,等我找到答案会补充,下面的解释都将使用“一个一个拿”这种机制。
当前这一轮微任务处理过程中
被执行,而不会等到下一个宏任务。这就是为什么在处理Promise链时,所有的.then回调会在一次事件循环中连续执行,而不会被其他宏任务(如setTimeout)打断。微任务队列全部执行完页面会重新渲染一次,然后执行宏任务,在 vue 和 react 中,我们经常为了确保一段代码在dom渲染后执行而把代码写在setTimeout中,这就是原因。
requestAnimationFrame 处于渲染阶段,不在微任务队列,也不在宏任务队列
jsvar a【p1】 = new Promise(res => { setTimeout(res); }); a.then【p2】(() => { console.log(1); }) .then【p3】(() => { console.log(2); }) .then【p4】(() => { console.log(3); }); a.then【p5】(() => { console.log(4); }) .then 【p6】(() => { console.log(5); }) .then 【p7】(() => { console.log(6); }); setTimeout(() => { console.log(7); Promise.resolve().then(() => { console.log(8); }); }); setTimeout(() => { console.log(9); }); Promise.resolve().then(() => { console.log(10); }); console.log(11); // 11,10,1,4,2,5,3,6,7,8,9
任务 | 当前执行代码 |
---|---|
渲染主线程 | 全局代码 |
微任务 | |
宏任务 |
jsp1 = pending【 待执行 () => {console.log(1);} 】 p2 = pending【 待执行 () => {console.log(2);} 】 p3 = pending【 待执行 () => {console.log(3);} 】 P4 = pending【 无待执行 】 p1 = pending【 待执行 () => {console.log(1); console.log(4);} 】 p5 = pending【 待执行 () => {console.log(5);} 】 p6 = pending【 待执行 () => {console.log(6);} 】 p7 = pending【 无待执行 】 () => { console.log(7); Promise.resolve().then(() => { console.log(8); }); } 进入定时器任务 () => {console.log(9)} 进入定时器任务 () => {console.log(10)} 进入微队列
console.log(11); 直接执行,此时控制台打印11
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => { console.log(10);} |
宏任务 | res , () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => { console.log(10);} |
微任务 | |
宏任务 | res , () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
执行() => { console.log(10);}, 此时控制台打印 10
任务 | 当前执行代码 |
---|---|
渲染主线程 | res |
微任务 | |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => {console.log(1);}, () => {console.log(4);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(1);} |
微任务 | () => {console.log(4);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
执行() => {console.log(1);}, 此时控制台打印 1
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => {console.log(4);} () => {console.log(2);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(4);} |
微任务 | () => {console.log(2);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
执行() => {console.log(4);}, 此时控制台打印 4
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => {console.log(2);} () => {console.log(5);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(2);} |
微任务 | () => {console.log(5);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
执行() => {console.log(2);}, 此时控制台打印 2
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => {console.log(5);} () => {console.log(3);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(5);} |
微任务 | () => {console.log(3);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
执行() => {console.log(5);}, 此时控制台打印 5
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => {console.log(3);} () => {console.log(6);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(3);} |
微任务 | () => {console.log(6);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
执行() => {console.log(3);}, 此时控制台打印 3
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => {console.log(6);} |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(6);} |
微任务 | |
宏任务 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} () => {console.log(9);} |
执行() => {console.log(6);}, 此时控制台打印 6
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(7);Promise.resolve().then(() => {console.log(8);});} |
微任务 | |
宏任务 | () => {console.log(9);} |
执行() => {console.log(7);Promise.resolve().then(() => {console.log(8);});} , 此时控制台打印 7
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | () => {console.log(8);} |
宏任务 | () => {console.log(9);} |
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(8);} |
微任务 | |
宏任务 | () => {console.log(9);} |
执行() => {console.log(8);}, 此时控制台打印 8
任务 | 当前执行代码 |
---|---|
渲染主线程 | () => {console.log(9);} |
微任务 | |
宏任务 |
执行() => {console.log(9);}, 此时控制台打印 9
任务 | 当前执行代码 |
---|---|
渲染主线程 | |
微任务 | |
宏任务 |
jsPromise.resolve().then(() => { console.log("1"); Promise.resolve().then(() => { console.log("2"); }); }); Promise.resolve().then(() => { console.log("3"); Promise.resolve().then(() => { console.log("4"); }); }); setTimeout(() => { console.log("5"); Promise.resolve().then(() => { console.log("6"); }); }); setTimeout(() => { console.log("7"); });