为何被拒Promise未被test捕获,出现UnhandledPromiseRejection?
问题分析与解决
核心原因
问题出在Promise的执行时机上:
function2()被push进promises数组时会立刻执行,它返回的Promise瞬间就被拒绝了。- 但此时
function1里的sleep(1000)还在等待,要1秒后才会调用Promise.all(promises)。 - 在这1秒的窗口里,这个被拒绝的Promise没有任何错误处理逻辑(既没有
.catch(),也没被Promise.all接管),所以Node.js会触发UnhandledPromiseRejection错误。 - 虽然1秒后
Promise.all会把这个拒绝传递给test的catch,但错误已经在Promise拒绝的那一刻被标记为未处理,为时已晚。
解决方案
有两种常见的修复方式:
方式1:延迟执行function2,让Promise.all立刻接管错误
把function2()的调用放到sleep的回调里,确保Promise被创建时就立刻被Promise.all监控:
const sleep = require("sleep-promise"); function function1() { return sleep(1000).then(() => { const promises = []; promises.push(function2()); // 此时创建Promise,立刻被Promise.all接管 return Promise.all(promises); }); } function function2() { return new Promise((resolve, reject) => { reject("failed"); }); } async function test() { try { await function1(); } catch (e) { console.log(e); // 会输出"failed" } } test();
方式2:给function2的Promise临时加catch,避免未处理错误
如果必须提前创建Promise,可以先给它加一个临时catch,等Promise.all处理时再传递错误:
const sleep = require("sleep-promise"); function function1() { const promises = []; // 临时捕获错误,避免未处理拒绝,后续Promise.all会重新抛出 promises.push(function2().catch(err => Promise.reject(err))); return sleep(1000).then(() => { return Promise.all(promises); }); } function function2() { return new Promise((resolve, reject) => { reject("failed"); }); } async function test() { try { await function1(); } catch (e) { console.log(e); // 会输出"failed" } } test();
内容的提问来源于stack exchange,提问作者Jaroslav
相关产品推荐
相关产品推荐

