返回未resolve的Promise时await未按预期执行的原因
问题原因解析
核心差异在于Node.js(以及多数JS运行环境)的进程退出机制,以及Promise是否绑定了回调函数:
第一种情况(await 未resolve的Promise)
当执行await neverResolve()时:
neverResolve()返回一个永远处于pending状态的Promise,且这个Promise没有绑定任何then()/catch()回调。await会暂停当前async函数的执行,等待Promise状态改变,但这个Promise永远不会resolve或reject。- 此时事件循环中没有需要处理的异步任务(这个Promise内部只有同步打印逻辑,未触发任何异步操作),Node.js会判定“没有需要等待的活跃任务”,直接终止进程。后续的
await setTimeout(...)和console.log("END")完全没有执行机会。
第二种情况(绑定then/catch回调)
当执行neverResolve().then().catch()时:
- 给这个永远pending的Promise绑定了回调函数,Node.js会将这个Promise标记为“存在待处理的回调”,因此不会轻易终止进程。
- 同时,
await new Promise(...)中的setTimeout会向事件循环中添加一个异步任务,程序会等待5秒后执行该任务的resolve逻辑,之后继续运行async函数的后续代码,最终打印END。
额外补充:即使Promise永远pending,只要它绑定了then()/catch()回调,运行环境就会认为存在需要跟踪的异步相关逻辑,不会随意退出进程。而单纯await一个无回调的pending Promise,因为没有触发任何异步任务,运行环境会直接结束进程。
内容的提问来源于stack exchange,提问作者Anonymous Zombie
相关产品推荐
相关产品推荐

