如有错误欢迎指正,谢~
我们都知道js是单线程语言,也就是只有一个线程,常称为主线程,在该线程中包含任务队列和执行栈
任务队列:
一些异步操作会将相关回调添加到任务队列中,而且不同的异步操作添加到队列的时间也不一样。
eg:
①onclick 等异步是当事件触发立即会将回调放到任务队列中。
②settimeout 会等到延迟时间到了再把回调放到任务队列中。
③像网络请求ajax是等到请求完成的时候再把回调放到任务队列中去。
执行栈:
执行栈就相当于一个全局方法,主方法,里面有个同步任务和异步任务,主线程在执行碰到同步任务就执行,碰到异步任务就将其回调放到任务队列中,执行完同步任务之后,就开始执行任务队列了
具体怎么划分看下面:
macrotasks(就是我们平常说的任务队列)和microtasks的划分:
macrotasks包括:script (整体代码),setTimeout,setInterval,setImmediate,
microtasks包括:process.nextTick,Promises,Object.observe,MutationObserver
宏观任务和微观任务可以这么理解:
宏观任务1 队列 -------------------对应一个微观任务--------------- 微观任务1队列
宏观任务2 队列 -------------------对应一个微观任务--------------- 微观任务2队列
... ...
宏观任务n 队列 -------------------对应一个微观任务--------------- 微观任务n队列
执行全部宏观任务队列1之后再去取微观全部1任务执行,任何执行完 ,第二轮宏观任务2队列执行全部执行完毕执行全部微观任务2,然后第3轮。。。。。循环下去
那么我们来看一个例子:
eg1:
1 setTimeout(function(){ 2 console.log(1) 3 },0); 4 new Promise(function(resolve){ 5 console.log(2) 6 for( var i=100000 ; i>0 ; i-- ){ 7 i==1 && resolve() 8 } 9 console.log(3) 10 }).then(function(){ 11 console.log(4) 12 }); 13 console.log(5);
结果是
2,3,5,4,1
eg2:
1 setTimeout(function(){ 2 console.log(1) 3 },0); 4 setTimeout(function(){ 5 console.log(6) 6 },2000); 7 new Promise(function(resolve){ 8 console.log(2) 9 for( var i=100000 ; i>0 ; i-- ){ 10 i==1 && resolve() 11 } 12 console.log(3) 13 }).then(function(){ 14 console.log(4); 15 setTimeout(function(){ 16 console.log(8) 17 },1000) 18 }); 19 console.log(5);
这个执行结果是啥呢???想想
结果是:
2,3,5,4,1,8,6
eg3:
setImmediate(function(){ console.log(1); },0); setTimeout(function(){ console.log(2); },0); new Promise(function(resolve){ console.log(3); resolve(); console.log(4); }).then(function(){ console.log(5); }); console.log(6); process.nextTick(function(){ console.log(7); }); console.log(8);
node 环境下:
3,4,6,8,5,1,2,7
浏览器环境下:
settimeout 优先级大于 setImmediate
nextTick 优先级 大于 promise
3,4,6,8,7,5,2,1
eg4:
//加入两个nextTick的回调函数 process.nextTick(function () { console.log('nextTick延迟执行1'); }); process.nextTick(function () { console.log('nextTick延迟执行2'); }); // 加入两个setImmediate()的回调函数 setImmediate(function () { console.log('setImmediate延迟执行1'); // 进入下次循环 process.nextTick(function () { console.log('强势插入'); }); }); setImmediate(function () { console.log('setImmediate延迟执行2'); }); console.log('正常执行');
浏览器环境下:正常执行,nextTick延迟执行1,nextTick延迟执行2,setImmediate延迟执行1,强势插入,setImmediate延迟执行2
1 async function async1(){ 2 console.log("async1 start"); 3 await async2(); 4 console.log("async1 end"); 5 } 6 async function async2(){ 7 console.log("async2"); 8 } 9 console.log("script start"); 10 setTimeout(function(){ 11 console.log("settimeout"); 12 },0); 13 async1(); 14 new Promise(function(resolve){ 15 console.log("promise1"); 16 resolve() 17 }).then(function(){ 18 console.log("promise2"); 19 }) 20 console.log("script end");
//结果
script start
async1 start
async2
promise1
script end
promise2
async1 end
settimeout
宏任务1队列:script start , async1 start , async2 ,promise1 , script end ----微任务队列1:promise2 (undefined) => { }(await Promise.resolve(undefined)的then(undefined){ (undefined) => { 这里才能拿到resolve的结果为undefined, 这是一个回调,异步操作,所以放到微任务中}})
宏任务2队列:settimeout -----微任务队列2 空空如也
总结一下,便于自己学习,也分享大家一起学习。(#^.^#)