[英]What is the proper way to handle errors in a promise?
我已经看到了几种不同的错误处理模式。
一种是这样的:
let result;
try {
result = await forSomeResult(param);
} catch {
throw new Error();
}
另一个是这样的:
const result = await forSomeResult(param).catch(() => throw new Error());
我更喜欢后者,因为它看起来更简洁。 但我也听说第一个解决方案更好,因为可能存在一些竞争条件,即在运行下一个命令之前.catch
不执行。
我想知道是否有人有关于为什么一种方法比另一种更好的技术答案。
首先,没有理由catch
并throw
或.catch()
并throw
除非您要在 catch 处理程序中执行其他操作或抛出不同的错误。 如果您只想抛出相同的错误并且不执行任何其他操作,那么您可以跳过catch
或.catch()
并将原始承诺拒绝返回给调用者。
然后,通常不建议您将await
与.catch()
混合使用,因为代码不太容易理解。 如果您想从await
捕获异常,请使用try/catch
绕过它。 .catch()
有效,如果您已经await
承诺,它就不是首选样式。
这两种风格之间的一个技术区别:
async function someFunc()
let x = await fn().catch(err => {
console.log(err);
throw err;
});
// do something else with x
return something;
}
和这个:
async function someFunc()
let x;
try {
x = await fn();
} catch(err) {
console.log(err);
throw err;
}
// do something else with x
return something;
}
是如果你调用的函数fn()
同步抛出(它不应该被设计,但可能是偶然的),那么try/catch
选项也将捕获该同步异常,但.catch()
不会。 因为它在async
函数中, async
函数将捕获同步异常并将其自动转换为拒绝的承诺,以便调用者将其视为拒绝的承诺,但不会在您的.catch()
记录或处理处理程序。
使用await
进行try/catch
更有益的情况之一是当您有多个await
语句并且您不需要单独处理其中任何一个的错误时。 然后,您可以用一个try/catch
它们包围起来,并在一个地方捕获所有错误。
async function someFunc(someFile) {
let fileHandle;
try {
// three await statements in a row, all using same try/catch
fileHandle = await fsp.open(someFile);
let data = await fsp.read(...);
// modify data
await fsp.write(...)
} catch(err) {
// just log and re-throw
console.log(err);
throw err;
} finally {
// close file handle
if (fileHandle) {
await fileHandle.close();
}
}
}
这取决于。
您是否要调用多个可能出错的异步函数? 您可以将它们全部包装在 try/catch 中并执行常见的错误处理,而无需重复自己:
try {
result = await forSomeResult(param);
await forSomeOtherResult();
return await finalResult(result);
} catch { //catches all three at once!
throw new Error();
}
您是否只需要处理这个特定调用的错误? .catch() 模式很好。 无需担心竞争条件, await
承诺解决或拒绝,这包括附加到承诺的所有成功和失败回调。 但是,在您的示例中,您捕获错误只是为了抛出一个空错误 - 在这种情况下,最好简单地编写以下代码:
const result = await forSomeResult(param);
...并让错误自然地传播给调用者。
我已经看到两种风格的混合使用足够普遍,我认为无论哪种方式都很好 - 它们每个都有特定的强度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.