Event Loop
作用:js 是一门单线程语言,就造成了在执行中如果遇到比较耗时的程序就会一直等待,影响用户体验。所以有了event loop 来解决这个问题
ES6 新增机制
- macrotask(宏任务): script 主代码块、setTimeout、setInterval、requestAnimationFrame、node 中的setimmediate 等。
- microtask(微任务): Promise.then catch finally、MutationObserver、node 中的process.nextTick 等。
微任务跟在对应的宏任务后执行
console.log(1)
setTimeout(() => {
console.log(2)
})
new Promise(resolve => {
console.log(3)
resolve()
}).then(() => {
console.log(4)
Promise.resolve()
.then(() => {
console.log(5)
})
.then(() => {
console.log(6)
})
})
console.log(7)
//结果
1 3 7 4 5 6 2
- 宏任务执行(javascript)
console.log(1)
- Macrotask Queue []
- Microtask Queue [] console 1
- 宏任务执行(setTimeout) 生成一个回调函数,排在
javascript
后边- Macrotask Queue [
javascript,setTimeout
] - Microtask Queue []
- Macrotask Queue [
- 微任务 Promise 同步执行
console.log(3)
并把.then
放入到了微任务队列- Macrotask Queue [
javascript,setTimeout
] - Microtask Queue [
log(4).then(log(5)).then(log(6))
] console 1 3
- Macrotask Queue [
- 同步执行
console.log(7)
- Macrotask Queue [
javascript,setTimeout
] - Microtask Queue [
log(4).then(log(5)).then(log(6))
] console 1 3 7
- Macrotask Queue [
- 先执行
javascript
的微任务console.log(4)
并生成新的微任务.then
- Macrotask Queue [
javascript,setTimeout
] - Microtask Queue [
then(log(5)).then(log(6))
] console 1 3 7 4
- Macrotask Queue [
- 执行 javascript 的微任务
console.log(5)
并生成新的微任务.then
- Macrotask Queue [
javascript,setTimeout
] - Microtask Queue [
.then(6)
] console 1 3 7 4 5
- Macrotask Queue [
- 执行 javascript 的微任务
console.log(6)
,javascript
宏任务执行完毕,移除执行栈- Macrotask Queue [
javascript,setTimeout
] - Microtask Queue [
.then(6)
] console 1 3 7 4 5 6
- Macrotask Queue [
- 执行下个宏任务
setTimeout
,consol.log(2)
- Macrotask Queue [
setTimeout
] - Microtask Queue [] console 1 3 7 4 5 6 2
- Macrotask Queue [
- 执行完成。
可以把浏览器理解成客栈,
`相亲相爱一家人`入住理解成一个宏任务,
`家庭成员`可能会有好多个微任务(比如先让你去拿个壶),并且执行中可能派生新的微任务(拿完之后还可能打壶水)
并且执行中还有`幸福一家人`入住
但是你不可能打水的过程中分身去招待另一家,只能先让他进入队列
当`相亲相爱一家人`的微任务执行完之后,另一个宏任务开始执行