javascript - 为什么要将 Promise 包装在 try/catch 块中?
问题描述
我一直在阅读 Eloquent JavaScript ,尤其是关于异步编程的这一章。我大部分时间都在理解它,但是其中一个例子让我迷失了。这是那个例子:
function requestType(name, handler) {
defineRequestType(name, (nest, content, source,
callback) => {
try {
Promise.resolve(handler(nest, content, source))
.then(response => callback(null, response),
failure => callback(failure));
} catch (exception) {
callback(exception);
}
});
}
我试图弄清楚为什么作者将 Promise 包装在 try/request 块中。为了解释它,作者这样说:
请注意,对处理程序的调用必须包装在 try 块中,以确保将其直接引发的任何异常都提供给回调。这很好地说明了使用原始回调正确处理错误的难度——很容易忘记正确路由这样的异常,如果你不这样做,故障将不会被报告给正确的回调。Promise 使这大部分是自动的,因此不易出错。
但这让我感到困惑,因为就在不久之前,他说:
Promise 使这更容易。它们可以被解决(操作成功完成)或被拒绝(失败)。仅当操作成功时才调用解析处理程序(在 then 中注册),并且拒绝会自动传播到 then 返回的新承诺。并且当处理程序抛出异常时,这会自动导致其 then 调用产生的承诺被拒绝。因此,如果异步操作链中的任何元素失败,则整个链的结果将被标记为被拒绝,并且在失败点之外不会调用任何成功处理程序。
那么为什么我不能把它写成:
function requestType(name, handler) {
defineRequestType(name, (nest, content, source,
callback) => {
Promise.resolve(handler(nest, content, source))
.then(response => callback(null, response),
failure => callback(failure));
.catch(reason => callback(reason));
});
}
它与作者使用.then(response, failure)
而不是有关.then(response).catch(failure)
吗?上面这个例子是为了处理成功、失败响应的成功交付(比如使用了不正确的请求类型)和完全失败的交付,所以也许与此有关?我在这里阅读了其他几个类似的问题,但我仍在努力将其应用于这些示例,因此非常感谢任何帮助。
解决方案
请记住,handler
函数是函数。这意味着在将结果值传递给Promise.resolve
该handler
函数可能如下所示:
function handler(nest, content, source) { throw new Error(); }
因此,它甚至不会去里面的“无极世界” Promise.resolve
。这就是为什么需要使用 try-catch 构造。所以无论失败(无论是承诺阶段还是handler
函数处理)都将由回调处理。
推荐阅读
- python - pyspark 在数据框中删除行以在一列中只有 X 个不同的值
- nginx - nginx docker 容器无法读取 certbot 证书
- r - 如何交叉制表跨同一字段的汇总值
- sh - 将变量分配给 shell 脚本中的每一行并稍后使用它们
- c# - .NET Core API 使用多个身份验证方案的问题
- c# - 将 avalonia 应用程序与某个自定义扩展名相关联,并在双击或使用 osX 中 finder 中的选项打开时处理文件
- autodesk-forge - 为什么更新的伪造查看器的模型浏览器隔离项目而不是选择?
- javascript - 如何防止用户输入重复的电子邮件?
- reactjs - styled-components:使用额外的样式扩展现有组件
- java - Can't import "import com.google.firebase.firestore.MetadataChanges" 原来的问题仍然没有答案