浏览器
先看两个例子,了解了输出结果在浏览器的事件循环基本清楚了
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')
})
})
输出结果 1,7,6,8,2,4,3,5,9,11,10,12
第二个例子
Promise.resolve().then(()=>{console.log('Promise1')
setTimeout(()=>{console.log('setTimeout2')
},0)
})
setTimeout(()=>{console.log('setTimeout1')
Promise.resolve().then(()=>{console.log('Promise2')
})
},0)
输出结果:Promise1,setTimeout1,Promise2,setTimeout2
几个概念
-
执行栈
- 同步代码执行,包括执行上下文,作用域链,this
-
micro task
- promise 的回调,process.nextTick()
-
macro task
- 定时器,渲染,I/O,script
一句话描述
一次 event loop 的过程是什么,遵循什么流程
1. 代码执行的时候从 script 开始,这是一个宏任务
2. 当前宏任务所有的同步任务立刻执行,当前的微任务进入队列,在同步任务执行完之后开始执行
3 如果还有宏任务,会添加到宏任务队列,按先后执行
- 这里注意宏任务的微任务全部执行完才会去执行宏任务队列里的下一个
- 理解 microtask 的任务队列是每个 macrotask 执行完之后执行
4. 执行渲染操作,更新界面
5. 检查是否存在 Web worker 任务,如果有,则对其进行处理
区别
浏览器和 Node 环境下,microtask 任务队列的执行时机不同
- Node 端,microtask 在事件循环的各个阶段之间执行
- 浏览器端,microtask 在事件循环的 macrotask 执行完之后执行