宏任务,微任务学习笔记

294 阅读2分钟

同步任务

主线程上排队执行的那些任务,只有前一个任务执行完毕,才能执行后一个任务

异步任务

由JavaScript 委托给宿主环境进行执行的任务,当异步任务执行完成后,会通知JavaScript 主线程执行异步任务的回调函数

宏任务

  • script(整体代码)
  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI render

微任务

  • promise
  • nextTick
  • Async/Await(实际就是promise)
  • MutationObserver(html5新特性)

事件循环

执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务队列是否为空,如果为空的话,就执行宏任务,否则就一次性执行完所有微任务。
每次单个宏任务执行完毕后,检查微任务(microTask)队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务(microTask)后,设置微任务(microTask)队列为null,然后再执行宏任务,如此循环。

cc12e7db5eda437facc1a881f1349b3d.gif

注意

Promise避坑

new Promise(() => {}).then() 

前面的 new Promise() 这一部分是一个构造函数,这是一个同步任务

后面的 .then() 才是一个异步微任务

console.log('1')

setTimeout(function callback(){
	console.log('2')
}, 1000)

new Promise((resolve, reject) => {
    console.log('3')
    resolve()
})
.then(res => {
    console.log('4');
})

console.log('5')

执行结果:1,3,5,42

async/await避坑

setTimeout(() => console.log(4))

async function test() {
  console.log(1)
  await Promise.resolve()
  console.log(2)
}

test()

console.log(3)

执行结果:1,3,2,4 可以理解为,await 以前的代码,相当于与 new Promise 的同步代码,await 以后的代码相当于 Promise.then的异步代码。

总结执行栈-->同步任务-->微任务-->宏任务-->执行栈-->新任务