use*_*963 18 javascript node.js async-await
我有一个异步函数,我希望在失败时抛出异常.但似乎有些事情阻止了这个:
通过省略try catch块,我希望抛出一个异常,我想在函数之外处理.
我得到的实际结果有点令人困惑:
(node:10636) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): E11000 duplicate key error index.
(node:10636) 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.
async f(obj) {
await db.collection('...').save(obj);
}
Run Code Online (Sandbox Code Playgroud)
当我尝试捕获异常并抛出其他内容时,我得到相同的结果:
async f(obj) {
try {
await db.collection('...').save(obj);
} catch(e) {
throw e.message;
}
}
Run Code Online (Sandbox Code Playgroud)
该函数是从try块调用的,所以不要看这是一个Unhandled Promise.
我想f用作另一个函数的参数:
g(obj, handler) {
try {
handler(obj);
} catch(e);
...
}
}
g(objToSave, f);
Run Code Online (Sandbox Code Playgroud)
rsp*_*rsp 17
async f(obj) {
try {
await db.collection('...').save(obj);
} catch(e) {
throw e.message;
}
}
Run Code Online (Sandbox Code Playgroud)
该函数是从try块调用的,所以不要看这是一个Unhandled Promise.
这里未处理的是拒绝f()函数返回的promise ,而不是.save()方法.所以这不会导致这个问题:
async f(obj) {
try {
await db.collection('...').save(obj);
} catch(e) {
console.error(e.message);
}
}
Run Code Online (Sandbox Code Playgroud)
在异步函数中抛出异常总是拒绝该函数返回的promise.
要捕获异常,您必须在另一个异步函数中执行此操作:
try {
asyncFunc();
} catch (err) {
// you have the error here
}
Run Code Online (Sandbox Code Playgroud)
或者您可以显式添加拒绝处理程序:
asyncFunc().catch(err => {
// you have the error here
});
Run Code Online (Sandbox Code Playgroud)
如果你正在捕获异常并抛出另一个异常,那么你会遇到同样的问题,只是在一个不同的函数中.
您必须添加一个promise拒绝处理程序,而不是抛出异常或在那里返回被拒绝的promise - 或者在处理异常的另一个异步函数中运行该函数,而不是重新抛出相同或新的异常.
总结一下:每个async函数都返回一个promise.每个承诺都需要一个拒绝处理程序.
拒绝处理程序使用双功能.then()或with .catch()或添加try { await asyncFunction(); } catch (err) { ... }
如果你有一个没有拒绝处理程序的承诺拒绝,你会在较旧版本的Node中收到警告,并在较新版本的Node中出现致命错误 - 请参阅此答案以获取更多详细信息:
rob*_*lep 10
最后,您要做的是在同步函数f中调用异步函数g,这将无法工作(这相当于能够将异步函数转换为同步函数).
相反,g要么必须要么async,或者它应该正确处理由返回的承诺f.但是,在此注释中,您声明所表示的函数f可能并不总是返回一个promise,在这种情况下,前一个选项最容易实现:
async g(obj, handler) {
return await handler(obj);
}
Run Code Online (Sandbox Code Playgroud)
如果handler不返回承诺,这也将起作用,但只是一个值(这里记录).
调用g(再次)需要异步函数或代码来处理其返回的promise:
g(objToSave, f).then(...).catch(...)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19634 次 |
| 最近记录: |