process.nextTick、Promises...、set

2021-07-20  本文已影响0人  small_Sun

首先执行主线程中的同步任务,当主线程任务执行完毕后,再从event loop中读取任务,例:

setTimeout(function(){console.log(1)},0);

console.log(2)

//输出2,1

首先需要了解Event Loop中的Job queue,
Event Loop:指主线程从“任务队列”中循环读取任务。

在Job queue中的队列分为两种类型:macro-task和microTask。
macro-task队列真实包含任务:
script(主程序代码),setTimeout, setInterval, setImmediate, I/O, UI rendering

micro-task队列真实包含任务:
process.nextTick, Promises, Object.observe, MutationObserver

由此我们得到的执行顺序应该为:

script(主程序代码)—>process.nextTick—>Promises...——>setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering

例1:

setTimeout(function(){console.log(1)},0);

new Promise(function(resolve,reject){
   console.log(2);
   resolve();
}).then(function(){console.log(3)
}).then(function(){console.log(4)});

process.nextTick(function(){console.log(5)});

console.log(6);
//输出2,6,5,3,4,1

这个例子就比较复杂了,这里要注意的一点在定义promise的时候,promise构造部分是同步执行的,这样问题就迎刃而解了。

首先分析Job queue的执行顺序:

script(主程序代码)——>process.nextTick——>promise——>setTimeout

I) 主体部分: 定义promise的构造部分是同步的,
因此先输出2 ,主体部分再输出6(同步情况下,就是严格按照定义的先后顺序)

II)process.nextTick: 输出5

III)promise: 这里的promise部分,严格的说其实是promise.then部分,输出的是3,4

IV) setTimeout : 最后输出1

综合的执行顺序就是: 2——>6——>5——>3——>4——>1

例2:

setTimeout(function(){console.log(1)},0);

new Promise(function(resolve,reject){
   console.log(2);
   setTimeout(function(){resolve()},0)
}).then(function(){console.log(3)
}).then(function(){console.log(4)});

process.nextTick(function(){console.log(5)});

console.log(6);

//输出的是  2 6 5 1 3 4

这种情况跟例1区别在于promise的构造中,没有同步的resolve,因此promise.then在当前的执行队列中是不存在的,只有promise从pending转移到resolve,才会有then方法,而这个resolve是在一个setTimout时间中完成的,因此3,4最后输出。

上一篇下一篇

猜你喜欢

热点阅读