函数返回Promise,检查错误

Function Returns a Promise, Check Errors

本文关键字:检查 错误 Promise 返回 函数      更新时间:2023-09-26

我有一个函数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库允许您这样做,并会为您报告未处理的拒绝——但在Q中,您没有自动检测这些失败的方法。

您必须使用.done或更改promise库。见鬼,即使是土生土长的承诺也能在几天内做到这一点。

Q特定解决方案:

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

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

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

现代图书馆与本土承诺

我已经根据Domenic和Petka的工作为promise库编写了一个规范,使其能够全局报告错误并与它们挂钩。一些图书馆已经实现了这一点,包括bluebird和when。Domenic正在为web浏览器制定一个并行规范。

目前支持或将在未来几周内支持的是:bluebird,when,es6 promise,rsvp和io中的native 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原生承诺会报告未经处理的拒绝,Chrome也会尝试,但目前还没有浏览器挂钩(不过它即将推出)。

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

您不能在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!
})