Open renmm opened 3 years ago
以一个宏任务(script(整体代码))开始,内部执行task,执行完当前所有的微任务队列后,单个宏任务完毕,返回值。 可以简单理解为2层循环,外层为宏任务循环,内存为微任务循环。
特点:
执行下看看,会输出啥
(function test() { setTimeout(function() { console.log(1) }, 0); //回调会被添加到macro-task队列 new Promise(function(resolve) { console.log(2); for (var i = 0; i < 10000; i++) { i == 9999 && resolve(); } console.log(3); }).then(function() { // then 1 console.log(4); new Promise(function(resolve) { setTimeout(function() { //回调会被添加到macro-task队列 resolve(); console.log(5); }, 0); console.log(6); }).then(function() { // then 2 console.log(7); //回调会在resolve后,添加到micro-task队列 }); }).then(function() { // then 3 console.log(10); new Promise(function(resolve) { setTimeout(function() { //回调会被添加到macro-task队列 resolve(); console.log(11); }, 0); console.log(12); }).then(function() { // then 4 console.log(13); //回调会在resolve后,添加到micro-task队列 }); }) console.log(8); return 9; })(); //控制台打印的结果如下: //2 //3 //8 //4 //6 //10 //12 //9 (此次是chrome输出的,干扰项,请忽略,因为多个语句块,也只返回最后一个,所以没有任何意义~) //1 //5 //7 //11 //13
从script开始(整体代码):
第一轮:
入栈: task = [ 2, 3, 8, ]
console: 2,3,8,
简化宏任务,实际是发起异步任务,异步任务执行完毕,再将cb存放到macro-task
macro-task = [ 1, ] micro-task = [ then 1 ]
执行micro-task: then 1 入栈: task = [4, 6] console: 4,6 macro-task = [ setTimeout(1), setTimeout(5) ] micro-task = [ then 3 ]
执行micro-task:then 3 入栈: task = [10, 12] macro-task = [ setTimeout(1), setTimeout(5), setTimeout(11) ]
setTimeout(1) 直接执行,没啥可说的 ... 执行macro-task: setTimeout(5) 入栈: task = [5] micro-task = [then 2]
最终console: 2,3,8,4,6,10,12 1, 5,7 11,13
能理解下面的,基本没问题了
let a = (function test() { setTimeout(function() { console.log(1) }, 0); //回调会被添加到macro-task队列 new Promise(function(resolve) { console.log(2); for (var i = 0; i < 10000; i++) { i == 9999 && resolve(); } console.log(3); }).then(function() { // then 1 console.log(4); new Promise(function(resolve) { setTimeout(function() { //回调会被添加到macro-task队列 resolve(); console.log(5); }, 0); console.log(6); }).then(function() { // then 2 console.log(7); //回调会在resolve后,添加到micro-task队列 }); }).then(function() { // then 3 console.log(10); new Promise(function(resolve) { setTimeout(function() { //回调会被添加到macro-task队列 resolve(); console.log(11); }, 0); console.log(12); }).then(function() { // then 4 console.log(13); //回调会在resolve后,添加到micro-task队列 }); }) console.log(8); return 9; })(); console.log(a) console.log(77); let b = (function test2 () { setTimeout(function() { console.log(21) }, 0); new Promise(function(resolve) { console.log(22); for (var i = 0; i < 10000; i++) { i == 9999 && resolve(); } console.log(23); }).then(function() { // then 1 console.log(24); new Promise(function(resolve) { setTimeout(function() { //回调会被添加到macro-task队列 resolve(); console.log(25); }, 0); console.log(26); }).then(function() { // then 2 console.log(27); //回调会在resolve后,添加到micro-task队列 }); }) console.log(88); return 99; })(); console.log(b) //控制台打印的结果如下: //2 //3 //8 //9 //77 //22 //23 //88 //99 //4 //6 //24 //26 //10 //12 //1 //21 //5 //7 //25 //27 //11 //13
event loop
以一个宏任务(script(整体代码))开始,内部执行task,执行完当前所有的微任务队列后,单个宏任务完毕,返回值。 可以简单理解为2层循环,外层为宏任务循环,内存为微任务循环。
特点:
执行下看看,会输出啥
分析:
从script开始(整体代码):
第一轮:
入栈: task = [ 2, 3, 8, ]
console: 2,3,8,
简化宏任务,实际是发起异步任务,异步任务执行完毕,再将cb存放到macro-task
macro-task = [ 1, ] micro-task = [ then 1 ]
执行micro-task: then 1 入栈: task = [4, 6] console: 4,6 macro-task = [ setTimeout(1), setTimeout(5) ] micro-task = [ then 3 ]
执行micro-task:then 3 入栈: task = [10, 12] macro-task = [ setTimeout(1), setTimeout(5), setTimeout(11) ]
setTimeout(1) 直接执行,没啥可说的 ... 执行macro-task: setTimeout(5) 入栈: task = [5] micro-task = [then 2]
最终console: 2,3,8,4,6,10,12 1, 5,7 11,13
能理解下面的,基本没问题了
参考 https://zhuanlan.zhihu.com/p/30894022 (图)