为何Promise.finally会晚于调用者的then执行?代码示例解析
为什么异步Promise代码输出是
1 2 A而非1 A 2? 先看这段异步JavaScript代码:
const a = () => { return new Promise((resolve) => { resolve(1); }); }; const b = () => { return new Promise((resolve) => { a() .then((aR) => { console.log(aR); resolve(2); }) .finally(() => { console.log("A"); }); }); }; const c = () => { b().then((bR) => { console.log(bR); }); }; c();
它的输出是1 2 A,而非直觉中的1 A 2。对比同步版本的代码:
const a = () => 1 const b = () => { try { const aR = a() console.log(aR) return 2 } finally { console.log("A") } }; const c = () => { try { const bR = b() console.log(bR) } catch {} }; c();
这段同步代码的输出是1 A 2,两者差异的核心在于Promise的finally与同步try/finally的执行逻辑不同:
同步逻辑中,
try块里的return 2会先计算出返回值,但不会立刻返回函数,而是先执行finally块的代码,之后才把返回值传递给调用方。所以执行顺序是:打印1→ 执行finally打印A→ 打印b()的返回值2。异步Promise逻辑中:
a()的then回调执行时,先打印1,接着调用resolve(2)——这会把b()返回的Promise标记为已完成状态,同时将b().then(...)的回调加入微任务队列等待执行。then回调执行完毕后,a()的finally回调被加入微任务队列。- 事件循环处理微任务队列时,会按队列顺序执行:先执行
b().then的回调打印2,再执行finally的回调打印A,最终输出1 2 A。
简单总结:同步finally是在函数返回前执行,而Promise的finally是微任务,会排在resolve触发的外部Promise回调之后执行。
内容的提问来源于Stack Exchange,提问作者typed-sigterm
相关产品推荐
相关产品推荐

