Node.js中Promise被外部try/catch处理,调用.finally仍触发未处理拒绝
问题解析:Promise.finally 触发未处理拒绝异常的原因
核心本质
Promise的finally()、then()、catch()方法都会生成全新的Promise实例,不会修改原Promise的状态或引用。你的代码中,调用promise.finally()后未处理该方法返回的新Promise的拒绝状态,导致Node.js的Promise检测机制捕捉到未处理的拒绝,抛出异常。
代码逐行拆解
foo函数中创建了一个直接被拒绝的原Promise:const promise = new Promise((resolve, reject) => { reject('my-error'); });- 调用
promise.finally()时,会返回一个新Promise。这个新Promise会继承原Promise的拒绝状态(原因仍为my-error),但你没有对这个新Promise做任何错误处理:promise.finally(() => { console.log('at foo'); }); - 你返回的是原Promise,
bar函数里的await和try/catch仅处理了原Promise的拒绝,但finally返回的新Promise的拒绝状态完全无人处理,因此触发了UnhandledPromiseRejection异常。
为何换成catch()就正常?
当替换为catch()时:
promise.catch(() => { console.log('at foo'); });
catch()方法返回的新Promise会被标记为已解决(resolved)——因为catch已经处理了原拒绝,默认返回一个状态为resolved的Promise(除非你在catch块中主动抛出新错误),自然不存在未处理的拒绝状态,也就不会触发异常。
修复方案
只需返回finally生成的新Promise,让bar中的try/catch一并处理其状态即可:
const foo = () => { const promise = new Promise((resolve, reject) => { reject('my-error'); }); // 返回finally创建的新Promise,而非原Promise return promise.finally(() => { console.log('at foo'); }); }
此时bar里的await会等待finally返回的新Promise,try/catch会处理它的拒绝状态,未处理拒绝的异常也就消失了。
内容的提问来源于stack exchange,提问作者Mohammed S. Yaseen
相关产品推荐
相关产品推荐

