JavaScript异步函数控制流疑问:.then回调为何先于后续代码执行?
问题:async函数中.then回调与后续代码的执行顺序疑问
在以下代码中,.then的回调函数先于console.log("still going on...")执行,但我原本以为.then的回调函数会先进入微任务队列,再进入调用栈,当前情况有何不同?原因是什么?
代码示例
async function test(){ console.log("start"); console.log("going on..."); await new Promise((resolve, reject) => {setTimeout(() => resolve("promise value"), 5000);}) .then((result) => console.log(result)) .catch((error) => console.log(error)); console.log("still going on..."); } test(); console.log("end.");
输出结果
start going on... end. promise value still going on...
解答
核心原因是:你这里的await等待的是整个Promise链的最终状态——也就是new Promise(...)调用.then().catch()之后返回的新Promise,而非仅等待初始Promise的resolve。
具体执行流程拆解:
- 调用
test()后,先同步执行console.log("start")和console.log("going on..."),随后遇到await。 - 此时创建初始Promise,内部的
setTimeout是宏任务,会在5秒后触发resolve。同时,我们为这个初始Promise挂载了.then和.catch,这两个方法会返回新的Promise,await就是在等待这个最终Promise完成。 - 5秒后,
setTimeout的回调执行,初始Promise变为fulfilled状态,它的.then回调(即console.log(result))被加入微任务队列;当当前宏任务执行完毕后,微任务队列被清空,该.then回调执行,输出promise value。 - 只有当这个
.then回调执行完成后,它返回的Promise(整个Promise链的最终Promise)才会变为fulfilled状态,此时await的等待结束,才会继续执行await之后的console.log("still going on...")。
这完全是正常的执行逻辑:await会阻塞async函数的后续代码,直到它等待的Promise(此处为整个.then链的结果)完成;而.then回调是整个Promise链的一部分,必须先执行完毕,才能让整个链的Promise进入完成状态,进而放行await之后的代码。
内容的提问来源于stack exchange,提问作者Manas Ghosh
相关产品推荐
相关产品推荐

