与在异步回调链中使用 try catch 块相比,返回异常有什么优势
What's the advantage of returning exceptions over using try catch blocks in async callback chain?
在查看了 Twisted 的 Deferred
类和 HeavyLifters 延迟库后,我注意到如果之前的结果值是 Failure
类的实例,则会触发错误。这让我思考:是否有任何特殊原因返回一个特殊对象来表示错误,而不仅仅是抛出错误。
根据我的推断,我觉得最好抛出错误,因为:
- 可以抛出任何值。
- 如果未捕获引发的值,则会向上传播调用堆栈。 不需要
- 特殊的
Failure
或Error
类。 - 它使回调看起来更像同步代码。
- 可以在调用堆栈的任何级别处理异常。
我注意到的一些缺点是:
- 尝试代码块并捕获错误可能会导致代码性能下降。
- 如果未捕获异常,则它将停止执行回调链的其余部分。
- 异步编程是必不可少的,与使用 try catch 块截然相反。
我正在尝试权衡几率,并找出哪种报告错误的方法更适合这种情况。
Twisted 中的 Failure
类有许多方便的方法,使其非常有用,独立于Deferred
中用于运行错误处理回调的功能。 浏览 API 文档,您会发现有用的方法,例如格式化回溯和检查异常类型。 Failure
也是一个方便的地方,可以放置一些非常粗暴的黑客,以便与twisted.internet.defer.inlineCallbacks
生成器以及生成微妙不同异常的 Cython 的特殊支持代码很好地集成。
Failure
也是将回溯状态与异常一起保存的好地方。 Python 异常通常不携带堆栈信息,所以如果你只有一个异常,你无法找到它在哪里引发。 每当你想要处理捕获它的except
块之外的异常时,这可能是一个主要缺点。
最后,能够返回Failure
可以实现以下简单且通常有用的模式:
def handleOneErrorCase(reason):
if not thisCaseApplies(reason):
return reason
handleThisCase(reason)
someDeferred.addErrback(handleOneErrorCase)
这经常出现在使用Deferred
代码中。 它很方便,恰好在 CPython 上性能更高一些,并且还具有保留 reason
中的原始堆栈信息的优点(如果错误处理程序重新引发异常,此时的堆栈将替换原始堆栈,从而掩盖异常的原始原因)。
错误通常在异步环境中通过回调返回,因为无法在异步函数外部捕获错误。例如,在javascript中,如果您尝试:
try {
setTimeout(function() { throw new Error(); }, 0);
} catch (e) {
console.log('Caught it.');
}
然后异常将无法捕获。这与异步函数被重新注册,然后由不同堆栈中的事件循环调用有关,因此异常不会冒泡原始堆栈。
- 节点导出返回一个空对象
- ES6构造函数返回基类的实例
- 监视函数从服务返回不起作用,但作用域函数起作用
- 控制台返回var不是't定义,但它是
- 从函数返回角度承诺
- Javascript返回值只在循环中返回一次
- 从控制器返回后Ajax启动事件激发
- 在javaservlet doPost方法中启动线程时,无法返回异常消息
- 角度过滤器返回异常结果
- 与在异步回调链中使用 try catch 块相比,返回异常有什么优势
- NodeJS + QUNIT:在测试中保存返回的异常
- 异步函数的 JavaScript 回调:是否有任何模式可以区分“返回值”和“异常”
- Angular Service在返回promise时抛出异常
- "闭合的“;属性异常返回“;window.open”;在JavaScript&歌剧
- 为什么,如果“$q.all”没有返回一个promise数组,则是一个未抛出的异常
- 服务返回异常数据
- AJAX返回异常状态码
- 当返回javascript代码时,如何在PHP/Dojo中正确生成异常
- XSJS总是从ajax调用返回异常结果集
- 当数组定义为3时,一个Javascript - forth值的神秘工作没有返回异常