为何JavaScript中Promise的错误抛出与finally执行顺序不符合预期?
问题原因解析
首先明确几个关键的执行顺序规则:
- Promise构造函数里的代码是同步执行的,会在当前宏任务里立刻跑完。
finally的回调属于Promise的微任务,会在当前同步代码全部执行完后,进入微任务队列排队执行。- 未被捕获的Promise拒绝错误(也就是没加
catch处理的rejection),会在所有微任务执行完毕之后,才会被引擎抛出并输出到控制台。
对应你的代码一步步拆解:
- 同步执行Promise构造函数:先打印
hi,接着抛出Error,把Promise标记为rejected状态,但此时这个错误还没被处理,暂时处于"待处理"状态。 - 调用
test.finally(),把console.log("why")这个回调加入微任务队列。 - 当前同步代码全部执行完,开始处理微任务队列:执行finally的回调,打印
why。 - 微任务队列清空后,引擎检测到有未处理的Promise拒绝,才输出那个
error的报错信息。
这就是实际输出顺序为hi → why → error的原因。
如果想让error在why之前输出,只要给Promise加个catch回调处理错误即可,示例代码:
const test = new Promise((resolve, reject) => { console.log("hi"); throw new Error("error"); }) test.catch(err => console.log(err.message)) .finally(() => { console.log("why") })
此时catch的回调会先于finally执行(微任务按注册顺序排队),输出顺序就会符合你的预期。
内容的提问来源于stack exchange,提问作者lome1446
相关产品推荐
相关产品推荐

