Skip to content
文档章节

微任务和宏任务

参考: 宏任务和微任务到底是什么

JavaScript 微任务和宏任务详解

JS执行任务是单线程,下一个任务必须等待当前任务执行结束才能执行。JS优先执行同步任务,对于异步任务,JS 会将其放入等待任务队列中,可分为宏任务队列和微任务队列。 当前任务直接结束,在执行下一个宏任务之前,会优先执行微任务队列中的任务,直到执行完毕,再执行宏任务。

宏任务:

宏任务 ---- setTimeout、setInterval、DOM事件、AJAX请求

微任务:

微任务 ---- Promise、async/await MutationObserve, Prosess.nextTick, queueMicroTask 等

微任务通常来说就是需要在当前 同步任务 执行结束后立即执行的任务,比如对一系列动作做出反馈,或者是需要异步的执行任务而又不需要分配一个新的任务,这样便可以减小一点性能的开销。

执行顺序

先来看一段代码,在来探讨执行顺序

js
console.log(1)
    setTimeout(() => {
      console.log(2)
    })
    Promise.resolve().then(() => {
      console.log(3)
    }).then(() => {
      console.log(5)
    })
    console.log(4)
复制代码

上面段代码打印的结果为1 4 3 5 2 。从上面代码,可以得出他们的执行顺序是:

先执行同步代码,遇到异步宏任务时候则将异步宏任务放入宏任务队列中,遇到异步微任务的时候则将异步微任务放入微任务列表中,当所有的同步代码执行完毕后,在将异步微任务从列表中调入主线程执行,异步微任务执行完毕之后再将异步宏任务从队列中调入主线程执行,一直循环到素有任务执行完毕。

注意:微任务执行下先于页面渲染的

任务关系

宏任务是主流,当js开始被执行的时候,就是开启一个宏任务,在宏任务中执行一条一条的指令,宏任务可以同时拥有多个,但是会按照顺序一个一个执行。

每一个宏任务,后面都可以跟着一个微任务队列,如果微任务队列中有指令或者方法,则先执行。如果没有,则开始执行下一个宏任务,知道所有的宏任务执行完毕。

任务详解

为什么有了宏任务后,还是会有微任务的存在?那是因为宏任务太占用性能,当需要一些较早就准备好的方法,排在最后才执行的时候,又不想新增一个宏任务,那么就可以把这些方法,一个一个的放在微任务队列里面,在这个宏任务中的代码执行完后,就会执行微任务队列。

因此当前同步代码执行,遇到异步任务,如果是异步宏任务,放入下一轮宏任务队列,是异步微任务,放入微任务队列跟在当前宏任务屁股后面。微任务相当于宏任务的小尾巴,因此当前宏任务执行完,在它后面等着的异步微任务就会被立刻放入队列继续执行。而异步的宏任务需要等到下一轮,从而造成了异步中微任务在宏任务之前执行的情况。