转自前端
https://juejin.im/post/59e85eebf265da430d571f89
导图要表达的内容用文字来表述的话:node
同步和异步任务分别进入不一样的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。 当指定的事情完成时,Event Table会将这个函数移入Event Queue。 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
包括总体代码script,setTimeout,setInterval
Promise.then,Promise.catch, process.nextTick
注意:
1.
promise是当即执行的,它建立的时候就会执行,不存在将promise推入微任务中的说法;
resolve()是用来表示promise的状态为fullfilled,至关于只是定义了一个有状态的Promise,可是并无调用它;
promise调用then的前提是promise的状态为fullfilled;
只有promise调用then的时候,then里面的函数才会被推入微任务中
2.
script标签中的console.log()会当即执行
分析:promise
console.log('1'); setTimeout(function() { console.log('2'); process.nextTick(function() { console.log('3'); }) new Promise(function(resolve) { console.log('4'); resolve(); }).then(function() { console.log('5') }) })
process.nextTick(function() { console.log('6'); })
new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') }) setTimeout(function() { console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { console.log('11'); resolve(); }).then(function() { console.log('12') }) })
第一轮事件循环流程分析以下:异步
console.log
,输出1。setTimeout
,其回调函数被分发到宏任务Event Queue中。咱们暂且记为setTimeout1
。process.nextTick()
,其回调函数被分发到微任务Event Queue中。咱们记为process1
。Promise
,new Promise
直接执行,输出7。then
被分发到微任务Event Queue中。咱们记为then1
。setTimeout
,其回调函数被分发到宏任务Event Queue中,咱们记为setTimeout2
。宏任务Event Queue | 微任务Event Queue |
---|---|
setTimeout1 | process1 |
setTimeout2 | then1 |
上表是第一轮事件循环宏任务结束时各Event Queue的状况,此时已经输出了1和7。函数
咱们发现了process1
和then1
两个微任务。oop
process1
,输出6。then1
,输出8。好了,第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。post
那么第二轮事件循环从setTimeout1
宏任务开始:spa
process.nextTick()
,一样将其分发到微任务Event Queue中,记为process2
。new Promise
当即执行输出4,then
也分发到微任务Event Queue中,记为then2
。宏任务Event Queue | 微任务Event Queue |
---|---|
setTimeout2 | process2 |
then2 |
process2
和then2
两个微任务能够执行。process.nextTick()
分发到微任务Event Queue中。记为process3
。new Promise
,输出11。then
分发到微任务Event Queue中,记为then3
。宏任务Event Queue | 微任务Event Queue |
---|---|
process3 | |
then3 |
process3
和then3
。整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。
(请注意,node环境下的事件监听依赖libuv与前端环境不彻底相同,输出顺序可能会有偏差)线程