宏任务和微任务

什么是宏任务和微任务

JavaScript把异步任务又做了进一步的划分,异步任务又分为两类,分别是:

  1. 宏任务( macrotask)
    • 异步Ajax请求、
    • setTimeout、setlnterval、
    • 文件操作
    • 其它宏任务
  2. 微任务( microtask)
    • Promise.then、.catch和.finally
    • process.nextTick
    • 其它微任务

宏任务和微任务

划分依据

异步任务是根据任务的触发时机任务队列的不同来分为宏任务和微任务的。下面是它们的依据:

  1. 触发时机

    • 宏任务(Macro Task):宏任务是由 JavaScript 引擎外部的任务触发的,比如 DOM 事件(如点击事件、鼠标移动事件)、setTimeoutsetInterval、网络请求等。宏任务代表着一个独立的、顺序执行的任务单元,它们会被放入宏任务队列中等待执行。
    • 微任务(Micro Task):微任务是在当前任务执行完成之后立即执行的任务,它们一般是由 JavaScript 引擎内部触发的,比如 Promise 的状态改变、queueMicrotask 函数等。微任务的执行时机是在当前宏任务执行结束、事件循环进入下一次循环之前。
  2. 任务队列

    • 宏任务队列:宏任务队列中存放着各种宏任务,包括了 DOM 事件、定时器、I/O 操作等。在事件循环的每一轮中,只有一个宏任务会被执行。
    • 微任务队列:微任务队列中存放着微任务,它们的执行顺序是按照它们进入队列的顺序执行的。在每个宏任务执行结束后,会检查并执行所有的微任务,直到微任务队列为空。

因此,异步任务是根据触发时机和任务队列的不同而被分为宏任务和微任务的。这种分化使得 JavaScript 引擎能够灵活地处理异步任务,并根据执行上下文的情况来调度它们的执行顺序。

执行顺序

宏任务和微任务是交替执行的。
在 JavaScript 中,执行完同步任务后会先检查是否存在微任务,如果存在,则先执行微任务队列中的所有微任务。执行完所有微任务后,再去执行宏任务队列中的任务。
宏任务微任务执行顺序

  • 场景举例
    场景

  • 练习
    new Promise 是同步任务,其调用的.then是微任务
    练习2

  • 练习
    练习3