【问题标题】:Promises and generic .catch() statementsPromise 和通用 .catch() 语句
【发布时间】:2015-09-30 00:32:33
【问题描述】:

我正在为我的系统编写一个 API,它将 XHR 发送到服务器并返回一个应由调用者处理的承诺 - 到目前为止一切顺利。

对于每个 API 调用,我必须使用 .then.catch 调用,但通常(大约 75% 的时间).catch 引用的功能与使用 console.error 打印的功能相同。

我的问题是 - 有没有办法为我创建的每个承诺附加一个默认的 catch 语句?(比如说打印到控制台),以及我想要的每个承诺进一步处理拒绝,我会添加另一个 .catch 调用(甚至覆盖它)?

每个调用都有自己的 .catch 的简化示例:http://jsbin.com/waqufapide/edit?js,console

尝试实现所需行为的非工作版本:http://jsbin.com/nogidugiso/2/edit?js,console

在第二个示例中,我不只是返回 deferred.promise,而是返回一个带有附加 catch() 处理程序的承诺:

return deferred.promise.catch(function (error) {
  console.error(error);
});

在这种情况下,then catch 和 then 函数都会被调用。

我确实意识到 Q 公开了 getUnhandledReasons() 函数和 onerror 事件,但我真的不想为每个承诺使用 .done() 也不想构建某种计时器/间隔来处理未处理列表拒绝。

其他库(例如 bluebird)公开 onPossiblyUnhandledRejection 事件,我不得不承认这是一个更好的解决方案,但仍然不是我想要的。

【问题讨论】:

  • Q 从 1.3 开始支持 process.on('unhandledRejection',不幸的是我没有时间为浏览器编写它 - 欢迎请求请求。我热烈推荐蓝鸟 :)
  • 为什么onPossiblyUnhandledRejection 不是您想要的?不,没有办法将错误处理程序附加到 每个 承诺,无论如何你不希望这样,但是没有真正的方法来自动检测承诺链结束(不比 possiblyUnhandled… 更好) .
  • @Bergi 我在一个中心位置自动生成我的所有承诺,所以我可以简单地附加一个默认的catch 处理程序。
  • 也许我误解了……这就是你想要做的吗? jsbin.com/qoyopidaza/1/edit?js,console
  • Gilad 所有你需要的是在你的 catch 处理程序中添加 throw e,比如同步 try/catch

标签: javascript promise q bluebird


【解决方案1】:

Q 使用 NodeJS 进程引发 unhandledRejection。如果你不使用 NodeJS,你可以使用这个 Workaround:

// Simulating NodeJS process.emit to handle Q exceptions globally
process = {
    emit: function (event, reason, promise) {
        switch(event)
        {
            case 'unhandledRejection':
                console.error("EXCEPTION-Q> %s", reason.stack || reason)
                break;
        }
    }
}

【讨论】:

    【解决方案2】:

    我认为您要做的就是在记录异常后重新抛出异常,以便其他处理程序正确处理它:

    return deferred.promise.catch(function (error) {
      console.error(error);
      throw e; // rethrow the promise
    });
    

    【讨论】:

    • @GiladArtzi 当然,这就像在同步 catch 中当您想要处理错误但不将错误标记为已解决时。
    【解决方案3】:

    使用 bluebird Promises,您可以调用

    Promise.onPossiblyUnhandledRejection(function(error){
        // Handle error here
        console.error(error);
    });
    

    使用 iojs,您将拥有指定的 process.on('unhandledRejection') 处理程序 here。 (也值得一读thisthis

    据我所知,其他地方的原生 Promises 和 Q Promises 都不提供此功能。

    【讨论】:

    • 这有一个额外的好处(通过进程钩子)覆盖你只在你的蓝鸟实例中而不是全局上所做的事情。
    • 我认为 OP 只是想在他们的情况下重新抛出错误。我在手机上,所以无法接听。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多