【问题标题】:Function Returns a Promise, Check Errors函数返回一个 Promise,检查错误
【发布时间】:2015-02-10 16:49:57
【问题描述】:

我有一个函数doSomething(),它使用 Q 框架返回一个承诺链。内容类似于:

loadDataSet : function (params) {

    return Q.fcall(function() {
        //Do Something
    })
    .then(function(){
       //Do Something Else
       throw New Error('unexpected error');
    });
}

调用代码类似于:

var promise = loadDataSet(args);

我想弄清楚是否引发了该错误。注意,在loadDataSet函数实现中,我没有使用.done()函数。

到目前为止,我的代码看起来像这样,但未能成功捕获错误并适当地处理它(这里,代码被修改,稍微从上面):

try {
    loadDataSet(args)
    .catch(function(error) {
       return error
    })
    .done();
}....

目标是处理来自 try-catch 块的错误。我错过了什么?

【问题讨论】:

  • 它是异步的。你只能使用 Promise 回调来处理它。
  • 你能举个例子吗?我对异步比较陌生。 Javascript 中的编程和回调的概念。也欢迎好的资源。
  • q readme 提供了大量示例,包括您正在尝试做的事情。

标签: javascript promise q


【解决方案1】:

好吧,这将是一个无赖。

你不能

虽然很多 Promise 库都允许您这样做,并且会为您报告未处理的拒绝 - 在 Q 中您没有自动检测这些失败的方法。

您必须使用.done 或更改承诺库。哎呀,即使是原生承诺are going to be able to do this in a few days

Q具体解决办法:

在 Q 中,您唯一现实的选择是使用 .done,与 then 不同,done 不会安全抛出,您可以从那里抛出异常并且它们不会被抑制 - 这需要您记住始终使用终止链done 但它有效:

myObj.loadDataSet(handleSuccess, handleError).done(); // will throw on rejection

在 Q 解决这个问题和其他问题之前,我不建议任何人使用它。

现代库和原生承诺

我已经根据 Domenic 和 Petka 的工作编写了一个 specification,以便承诺库能够在全球范围内报告错误并与它们挂钩。几个库已经实现了这一点,包括 bluebird 和 when。 Domenic 正在制定 Web 浏览器的并行规范。

目前支持或将在未来几周内支持的有:bluebird、when、es6-promise、rsvp 和 io 中的原生 promise。

// log any unhandled promise rejections
process.on('unhandledRejection', function(reason, p){
    console.log("Possibly Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging here
});

至于浏览器,类似:

window.addEventListener("unhandledrejection", function(e) {
    var reason = e.detail.reason;
    var promise = e.detail.promise;
    console.log("Unhandled rejection", promise, reason);
});

此协议的支持较少,但计划将其包含在本机承诺中。目前 Firefox 原生 promise 会报告未处理的拒绝,Chrome 也会尝试 - 但目前还没有浏览器挂钩(虽然它即将推出)。

请注意,团队正在开发非常有趣的工具。在与 Paul Irish 讨论后,我确信在浏览器中调试 Promise 的工具方面将会有很棒的事情发生,这将使原生 Promise 几乎与 Bluebird Promise 一样可调试(这太棒了!)。

【讨论】:

  • 很好的答案,但它与处理try catch 块中的错误的问题不匹配......
  • @Bergi 是的,我们都知道这是不可能的 :) OP 询问“我想弄清楚是否抛出了该错误。请注意,在 loadDataSet 函数实现中,我没有使用 .done() 函数。” - 他的 try/catch 示例只是为了说明解决特定案例问题的尝试。如果您认为这很重要,我不介意在答案中特别解决这个问题。
  • @BenjaminGruenbaum,太棒了。谢谢。
【解决方案2】:

你不能在then 中抛出异常,因为没有人能够捕捉到它。相反,创建一个新的 Q.defer 并在出现错误时对其调用拒绝

loadDataSet : function (params) {
    var deferred = Q.defer()
    Q.fcall(function() {
        //Do Something
    }).then(function(){
       //Do Something Else
       deferred.reject('error message')
    }, deferred.reject)
    return deferred.promise
}

然后像这样使用它

loadDataSet().then(function (data) {
    //ok, got data
}).catch(function (err) {
    //error!
})

【讨论】:

猜你喜欢
  • 2017-03-26
  • 2021-10-18
  • 2015-02-24
  • 2017-09-13
  • 2020-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
相关资源
最近更新 更多