函数 Returns 一个 Promise,检查错误

Function Returns a Promise, Check Errors

我有一个函数 doSomething() returns 承诺链,利用 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 块的错误。我错过了什么?

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

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!
})

好吧,这将是一个无赖。

你不能

虽然许多 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 和 native promises in io。

// 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 本机 promises 将报告未处理的拒绝,Chrome 也会尝试 - 但目前还没有浏览器挂钩(不过即将推出)。

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