2 回答
TA贡献2041条经验 获得超4个赞
当一个 Promise 拒绝时,必须在当前调用堆栈清除之前处理它,否则会出现未处理的拒绝。你有:
} catch (e) {
return Promise.reject(e)
} finally {
await cleanup() // remove await here and everything is fine
}
如果你 remove await,则在构造被拒绝的 Promise 后立即someFunctionThatReturnsRejectedPromise返回 ,因此被拒绝的 Promise 被in捕获。但是如果有任何延迟,被拒绝的 Promise不会立即处理;你的意愿意味着被拒绝的 Promise 在返回之前的一段时间内未处理,这意味着无法及时处理被拒绝的 Promise。Promise.reject(e)catchmainawait cleanup()someFunctionThatReturnsRejectedPromisemaincatch
您可以使用的另一种方法是将错误包装在 anError而不是 aPromise.reject中,然后检查结果是否为instanceof Errorin main:
window.addEventListener('unhandledrejection', () => console.log('unhandled rejection!'));
async function main() {
const result = await someFunctionThatReturnsRejectedPromise();
if (result instanceof Error) {
console.log('Error "caught" in main:', result.message);
}
}
async function someFunctionThatReturnsRejectedPromise() {
try {
await new Promise((resolve, reject) => {
setTimeout(() => {
reject('something went wrong')
}, 1000);
})
} catch (e) {
return new Error(e);
} finally {
await cleanup()
}
}
function cleanup() {
return new Promise(resolve => {
setTimeout(() => {
resolve('cleaup successful')
});
})
}
main();
TA贡献1845条经验 获得超8个赞
更新的答案替换
Promise.reject(e)与throw e;
所以函数变成
async function someFunctionThatReturnsRejectedPromise() {
try {
await new Promise((resolve,reject) => {
setTimeout(() => {
reject('something went wrong')
}, 1000);
})
} catch(e) {
throw e;
} finally {
await cleanup() // remove await here and everything is fine
}
}
原因
someFunctionThatReturnsRejectedPromise方法拒绝第Promise一个。所以控制流转到方法main捕获块。后来cleanup的方法尝试做同样的事情。也就是拒绝已经拒绝的承诺。因此你得到错误
Promise.rejectthrow与子句有点不同。请参考throw vs Promise.reject
这就是为什么删除awaitfromcleanup()或删除returnfromcleanup方法有效的原因。因为这将Promise与当前控制流分离。
添加回答
举报