为啥延迟处理承诺拒绝有时会导致 UnhandledPromiseRejectionWarning?
Posted
技术标签:
【中文标题】为啥延迟处理承诺拒绝有时会导致 UnhandledPromiseRejectionWarning?【英文标题】:Why does delaying handling of promise rejections sometimes result in UnhandledPromiseRejectionWarning?为什么延迟处理承诺拒绝有时会导致 UnhandledPromiseRejectionWarning? 【发布时间】:2021-07-30 06:24:08 【问题描述】:当我运行以下代码时,为什么会收到未处理的 Promise 拒绝警告?
async function load()
throw new Error('error');
async function main()
const promise = load();
await new Promise(resolve => setTimeout(resolve, 5000));
try
await promise;
catch (e)
console.log('caught error', e);
main();
这是输出:
jkim@dev-jkim test $ node index.js
(node:25276) UnhandledPromiseRejectionWarning: Error: error
由于await promise
是一个try-catch,我很困惑为什么我的try-catch 没有捕捉到错误。我想这与setTimeout
有关,因为以下代码有效:
async function load()
throw new Error('error');
async function main()
const promise = load();
try
await promise;
catch (e)
console.log('caught error', e);
main();
jkim@dev-jkim test $ node index.js
caught error Error: error
这里发生了什么?如果在当前刻度结束时未处理承诺拒绝,是否会自动导致未处理的承诺拒绝警告?
(我在节点 v10.16.3 上)
【问题讨论】:
【参考方案1】:函数load()
抛出一个Error
。如果在处理Promise
时出现错误thrown
,则Promise
被拒绝。现在,如果错误 load()
没有被捕获,那么 JS 会抛出 UnhandledPromiseRejectionWarning
您的代码的更好说明是:
function load()
console.log("hello after some time");
const foo = new Promise((resolve, reject) =>
setTimeout(resolve, 5000);
)
.then(() => load(); )
.catch((e) => console.log(`Caught Error: $e`));
【讨论】:
【参考方案2】:如果在当前刻度结束时未处理承诺拒绝,是否会自动导致未处理的承诺拒绝警告?
是的。 Promise 必须在它被拒绝时附加一个拒绝处理程序,否则拒绝将被视为未处理。如果您稍后附加拒绝处理程序,例如在
await new Promise(resolve => setTimeout(resolve, 5000));
当解释器到达时,load
Promise 已被拒绝
try
await promise;
catch (e)
所以,虽然可以用.catch
捕获拒绝,但它没有被任何东西在拒绝的那一刻捕获,从而导致警告。
此类事情的最佳实践是始终立即附加拒绝处理程序 - 无论这意味着 .catch
,还是在 try
/catch
或 Promise.all
内,或者为调用者返回 Promise处理。
【讨论】:
以上是关于为啥延迟处理承诺拒绝有时会导致 UnhandledPromiseRejectionWarning?的主要内容,如果未能解决你的问题,请参考以下文章
为啥修改项目输出目录会导致:IOException is unhandled “Cannot locate resource 'app.xaml'.”