函数返回一个Promise,检查错误

时间:2015-02-09 19:06:35

标签: javascript promise q

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

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块的错误。我错过了什么?

2 个答案:

答案 0 :(得分:2)

嗯,这将是一个无赖。

你不能

虽然许多承诺库允许你这样做并且会报告未经处理的拒绝 - 在Q中你没有办法自动检测这些失败。

您必须使用.done 或更改承诺库。哎呀,甚至本土的承诺are going to be able to do this in a few days

Q特定解决方案:

在Q中,唯一可行的选择是使用.done,与then不同,完成不是安全的,你可以从那里抛出异常并且它们不会被压制 - 这需要你请记住始终使用done终止链,但它可以正常工作:

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

就个人而言,在Q修复此问题和其他问题之前,我不建议将其用于任何人。

现代图书馆和本土承诺

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

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

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

答案 1 :(得分:-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!
})