代码之家  ›  专栏  ›  技术社区  ›  Shashwat Tripathi

承诺有全局错误处理吗[重复]

  •  0
  • Shashwat Tripathi  · 技术社区  · 6 年前

    我有一个功能 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块的错误。我错过了什么?

    0 回复  |  直到 10 年前
        1
  •  2
  •   Benjamin Gruenbaum    10 年前

    好吧,这将是一个无赖。

    你不能

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

    你必须 使用 .done 或更改承诺库。见鬼,即使是本地人的承诺 are going to be able to do this in a few days .

    Q特定溶液:

    在Q中,你唯一现实的选择是使用 完成 ,不同于 then 完成并不是安全的抛出,您可以从中抛出异常,它们不会被抑制-这要求您记住始终使用 done 但它起作用:

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

    在Q解决这个问题和其他问题之前,我个人不能向任何人推荐使用它。

    现代图书馆与本土承诺

    我写了一篇 specification 基于Domenic和Petka为Promise图书馆所做的工作,它们能够在全球范围内报告错误并将其挂钩。一些库已经实现了这一点,包括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承诺一样可调试(这太棒了!).

        2
  •  -2
  •   Cranky    10 年前

    你不能在里面抛出异常 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!
    })