宏任务队列和微任务队列

setTimeout(function() {
  console.log(1);
}, 0);

new Promise(function (resolve, reject) {
  resolve(2);
}).then(console.log);

console.log(3);
// 3
// 2
// 1

关于微任务(Promise中的then回调)为什么早于宏任务(setTimeout)的执行时间可能需要更详细的解释

JavaScript中的事件循环分为两个主要部分:宏任务队列和微任务队列

宏任务包括像setTimeout这样的异步任务,而微任务包括Promise的then回调、async/await等。事件循环的执行顺序如下:

  1. 执行当前宏任务(同步代码)
  2. 执行所有微任务队列中的任务
  3. 从宏任务队列中取出下一个任务,执行它
  4. 重复步骤2和步骤3,直到宏任务队列和微任务队列都为空

根据这个执行顺序,让我们分析一下上面的代码:

  1. 首先,执行同步代码 console.log(3);,输出 3。

  2. 接下来,创建了一个Promise,并且立即调用了then方法。这个then回调被添加到微任务队列中,但并没有立即执行。

  3. 接着,执行 setTimeout(function() { console.log(1); }, 0);,它被添加到宏任务队列中,但由于传入的时间是0,它并不会立即执行。它将在下一轮事件循环的宏任务队列中执行。

  4. 当前宏任务(同步代码)执行完毕,进入微任务队列阶段。此时,执行 Promise 的 then 回调,输出 2。这是因为微任务队列中的任务会在当前宏任务执行完毕后立即执行。

  5. 现在,事件循环开始执行宏任务队列中的任务,取出 setTimeout 中的回调函数,输出 1。

所以,输出结果是 3、2、1,这就解释了为什么then回调早于setTimeout执行。微任务总是在当前宏任务执行完毕后立即执行,而宏任务(setTimeout)则需要等待下一轮事件循环开始时执行。这就是为什么 then 回调早于 setTimeout。

你可能感兴趣的:(JavaScript,javascript)