Javascript 宏任务和微任务

宏任务

由宿主发起的任务称为宏观任务。 例如setTimeout函数创建的就是宏任务,当前的脚本执行也是宏任务。

setTimeout(() => {
  console.log("Hello");
}, 100);

微任务

由 JavaScript 引擎发起的任务称为微任务。 微任务的主要来源是Promise。 在 JavaScript 的事件循环中,当期宏任务执行完或者如果调用栈为空的时候,会检查微任务队列,如果队列不为空,会执行微任务队列中的任务。

function createPromise(value) {
  new Promise((resolve, reject) => {
    if (value === 1) {
      resolve();
    } else {
      reject();
    }
  });
}

宏任务和微任务的结合的例子

以下是一个宏任务和微任务结合的例子。

function sleep(time) {
  return new Promise((resolve, reject) => {
    console.log("b");
    setTimeout(() => {
      console.log("c");
    }, time);
  });
}
sleep(10).then(() => {
  console.log("d");
});
console.log("a");

在浏览器中,这个脚本的输出将会是 b,a,d,c。 首先脚本执行的过程本身就是一个宏任务,执行到sleep的时候,进入到创建Promise的代码,这个时候输出a,遇到setTimeout会创建一个宏任务,并把回调放入宏任务队列中。执行到sleep(10).then的时候,会创建一个微任务。最后等到执行到console.log("a"),即脚本的最后一行的时候,当前脚本的宏任务就结束了,这个时候微任务队列不是空的,就会执行微任务队列中的任务。等到微任务队列为空的时候,又会执行下一个宏任务,即使用setTimeout创建的那个宏任务。

宏任务和微任务的具体执行的流程可以参考这篇文章https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/?utm_source=html5weekly。