【发布时间】:2020-08-03 21:05:59
【问题描述】:
我在我的 NodeJs 代码中使用了asyncawait,代码结构如下。
async function main(){
try {
await someFunctionThatReturnsRejectedPromise()
} catch(e) {
console.log(e)
}
}
async function someFunctionThatReturnsRejectedPromise() {
try {
await new Promise((resolve,reject) => {
setTimeout(() => {
reject('something went wrong')
}, 1000);
})
} catch(e) {
return Promise.reject(e)
} finally {
await cleanup() // remove await here and everything is fine
}
}
function cleanup() {
return new Promise(resolve => {
setTimeout(() => {
resolve('cleaup successful')
}, 1000);
})
}
main();
在 finally 块中,我正在做一些async 清理工作,肯定会解决。
但是这段代码正在抛出PromiseRejectionHandledWarning
(node:5710) UnhandledPromiseRejectionWarning: something went wrong
(node:5710) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:5710) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
something went wrong
(node:5710) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
据我所知,我不会在这里留下任何未处理的承诺。
我究竟做错了什么? finally 是否应该按设计同步阻止?如果是,为什么会这样?
更新 1:
如果我将someFunctionThatReturnsRejectedPromise 转换为良好的then 和catch,它可以正常工作:
function someFunctionThatReturnsRejectedPromise() {
return (new Promise((resolve,reject) => {
setTimeout(() => {
reject('something went wrong')
}, 1000);
})).catch(e => {
return Promise.reject(e)
}).finally(() => {
return cleanup()
})
}
更新 2:(了解问题)
如果我await返回Promise,问题就解决了。
return await Promise.reject(e)
这让我明白我做错了什么。
我打破了await 链(部分同义于在then/catch 语法中不返回Promise)。
谢谢大家:)
【问题讨论】:
-
抛出“DeprecationWarning”是因为您没有在
cleanup中为您的Promise提供拒绝策略。你永远不应该使用Promise构造函数(除非在一些非常特殊的非常罕见的情况下)。您还应该在await cleanup()上添加try-catch以处理可能的未处理拒绝。 -
@briosheje 正如我所提到的,“肯定会解决的清理”把它想象成一个永远不会抛出/拒绝的函数
-
再一次:只要涉及
await,就会创建Promise。如果你不处理该承诺的拒绝,节点会给你这样的警告。这是有意的,因为承诺可能会因任何类型的错误而被拒绝(无论是什么通用的 JAVASCRIPT 错误,不一定与承诺相关)。您必须删除await,或者用 try-catch 包围块。 -
@briosheje 即使我处理
cleanup,问题仍然存在
标签: javascript node.js promise async-await es6-promise