javascript - 等待 Promise.reject 或抛出错误以纾困?
问题描述
我正在将我的承诺链代码重构为异步/等待风格。这样做的原因之一是我想要一个单独的 catch 块来处理所有错误情况(如这里解释的了解 node.js 中的承诺拒绝)
我的问题是当我遇到同步错误时,我应该打电话await Promise.reject
还是throw error
退出这个过程?我知道任何一种方式都行,但我更喜欢throw error
。我已经知道我得到了无效的结果,为什么还要等待?使用 throw 立即终止控制流似乎是一个更好的选择。
我不是在谈论承诺链(我的问题的全部意义),所以我不认为线程JavaScript Promises - reject vs. throw回答了我的问题。
我阅读了Node.js 中的错误处理文章,我认为它也没有给出答案。但它确实说
给定的函数应该同步(使用 throw)或异步(使用回调或事件发射器)传递操作错误,但不能同时传递。... 一般来说,使用 throw 并期望调用者使用 try/catch 是非常罕见的......
我的异步函数可能会返回 Promise.reject。因此,我担心引入 2 种方法来传递该文章所针对的错误。
try {
let result = await aysncFunc().
if (!isResultValid(result)) { //isResultValid() is sync function
await Promise.reject('invalid result')
//or throw 'invalid result'
}
... //further processing
}
catch (error) {
...
}
解决方案
在 Promise 控制流中使用它在语义上是正确的throw
,这通常是摆脱 Promise 链的更可取的方式。
根据编码风格,await Promise.reject(...)
可用于区分实际错误和预期拒绝。带有字符串原因的拒绝承诺是有效的,但throw 'invalid result'
被认为是可以用linter 规则解决的样式问题,因为使用Error
实例作为异常是常规的。
它之所以重要的原因是因为无法检测到字符串异常instanceof Error
并且没有message
属性,一致的错误日志记录console.warn(error.message)
会导致undefined
条目模糊不清。
// ok
class Success extends Error {}
try {
throw new Success('just a friendly notification');
} catch (err) {
if (!(err instanceof Success)) {
console.warn(err.message);
throw err;
}
}
// more or less
const SUCCESS = 'just a friendly notification';
try {
await Promise.reject(SUCCESS);
} catch (err) {
if (err !== SUCCESS)) {
console.warn(err.message);
throw err;
}
}
// not ok
try {
throw 'exception';
} catch (err) {
if (typeof err === 'string') {
console.warn(err);
} else {
console.warn(err.message);
}
throw err;
}
由于invalid result
实际上是一个错误,因此将其设为一个是合理的:
throw new TypeError('invalid result');
我不是在谈论承诺链(我的问题的全部要点),所以我不认为线程 JavaScript Promises - reject vs. throw 回答了我的问题。
async
function 是 Promise 链的语法糖,因此适用于 Promise 的所有点也适用async
。
在某些情况下,抛出错误与拒绝 Promise 不同,但它们特定于其他 Promise 实现,例如 AngularJS $q
,并且不会影响 ES6 Promise。构造函数中的同步错误Promise
导致异常,这也不适用于async
.
推荐阅读
- java - HikariPool-1 - 池初始化期间出现异常,但我的 application.properties 中有正确的信息
- mongodb - MongoDB索引有什么用?
- python - 如何使用 date.range 创建列和绘图?
- r - 我试图比较有关 Soc 媒体的组以进行营销分析评估,但我被卡住了
- angular - 多个组件将节点与标记名按钮匹配
- flutter - Flutter Null 安全迁移说“包不存在”
- ios - 如何更改 SwiftUI TabView 点指示器位置?
- c# - 创建 MDI 子窗体单调模式
- x86 - x86 程序集:引导加载程序不加载程序
- ios - 点击 3d 模型并在 ARKit 中执行操作