浏览器事件循环(event loop)

263 阅读2分钟

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
  1. 宏任务执行(javascript) console.log(1)
    • Macrotask Queue []
    • Microtask Queue [] console 1
  2. 宏任务执行(setTimeout) 生成一个回调函数,排在javascript后边
    • Macrotask Queue [javascript,setTimeout]
    • Microtask Queue []
  3. 微任务 Promise 同步执行 console.log(3) 并把 .then 放入到了微任务队列
    • Macrotask Queue [javascript,setTimeout]
    • Microtask Queue [log(4).then(log(5)).then(log(6))] console 1 3
  4. 同步执行 console.log(7)
    • Macrotask Queue [javascript,setTimeout]
    • Microtask Queue [log(4).then(log(5)).then(log(6))] console 1 3 7
  5. 先执行 javascript 的微任务 console.log(4) 并生成新的微任务 .then
    • Macrotask Queue [javascript,setTimeout]
    • Microtask Queue [then(log(5)).then(log(6))] console 1 3 7 4
  6. 执行 javascript 的微任务 console.log(5) 并生成新的微任务 .then
    • Macrotask Queue [javascript,setTimeout]
    • Microtask Queue [.then(6)] console 1 3 7 4 5
  7. 执行 javascript 的微任务 console.log(6)javascript宏任务执行完毕,移除执行栈
    • Macrotask Queue [javascript,setTimeout]
    • Microtask Queue [.then(6)] console 1 3 7 4 5 6
  8. 执行下个宏任务 setTimeout ,consol.log(2)
    • Macrotask Queue [setTimeout]
    • Microtask Queue [] console 1 3 7 4 5 6 2
  9. 执行完成。
 可以把浏览器理解成客栈,
 `相亲相爱一家人`入住理解成一个宏任务,
 `家庭成员`可能会有好多个微任务(比如先让你去拿个壶),并且执行中可能派生新的微任务(拿完之后还可能打壶水)
 并且执行中还有`幸福一家人`入住
 但是你不可能打水的过程中分身去招待另一家,只能先让他进入队列
 当`相亲相爱一家人`的微任务执行完之后,另一个宏任务开始执行

借鉴自:segmentfault.com/a/119000001…