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等。事件循环的执行顺序如下:
- 执行当前宏任务(同步代码)
- 执行所有微任务队列中的任务
- 从宏任务队列中取出下一个任务,执行它
- 重复步骤2和步骤3,直到宏任务队列和微任务队列都为空
根据这个执行顺序,让我们分析一下上面的代码:
-
首先,执行同步代码 console.log(3);,输出 3。
-
接下来,创建了一个Promise,并且立即调用了then方法。这个then回调被添加到微任务队列中,但并没有立即执行。
-
接着,执行 setTimeout(function() { console.log(1); }, 0);,它被添加到宏任务队列中,但由于传入的时间是0,它并不会立即执行。它将在下一轮事件循环的宏任务队列中执行。
-
当前宏任务(同步代码)执行完毕,进入微任务队列阶段。此时,执行 Promise 的 then 回调,输出 2。这是因为微任务队列中的任务会在当前宏任务执行完毕后立即执行。
-
现在,事件循环开始执行宏任务队列中的任务,取出 setTimeout 中的回调函数,输出 1。
所以,输出结果是 3、2、1,这就解释了为什么then回调早于setTimeout执行。微任务总是在当前宏任务执行完毕后立即执行,而宏任务(setTimeout)则需要等待下一轮事件循环开始时执行。这就是为什么 then 回调早于 setTimeout。