链接失败的承诺

时间:2014-05-31 15:32:01

标签: javascript angularjs promise angular-promise

看看这个blog对承诺的处理后,我修改了失败的例子:

var myApp = angular.module('myApp',[]);

myApp.controller("MyCtrl", function ($q, $scope) {

    (function() {
        var deferred = $q.defer();
        var promise = deferred.promise;
        promise.then(function(result) {
            console.log("success pass 1 - " + result);
            return result;
        }, function(reason) {
            console.log("failure pass 1, reason:", reason);
            throw new Error("failed with: " + reason);
        }).
        then(function(result) {
            console.log("2nd success! result: ", result);
        }, function(reason) {
            console.log("2nd failure! reason: ", reason);
        });


        console.log("calling deferred.reject('bad luck')");
        deferred.reject("bad luck");

    })();

对于我的第一个失败函数,我注意到用throw替换return会导致:

calling deferred.reject('bad luck') 
failure pass 1, reason: bad luck 
2nd success! result:  Error {stack: (...), message: "failed with: bad luck"}

因此,我将return替换为throw以获得所需的failure -> failure结果。

calling deferred.reject('bad luck') 
failure pass 1, reason: bad luck 
Error: failed with: bad luck at ...app.js
2nd failure! reason: Error {stack: ... "failed with: bad luck"}

抛出的错误似乎没有被捕获。这是为什么?内部失败的情况不应该抓住这个引发的错误吗?

此外,在链式承诺中,只能通过抛出Error来达到连续的错误情况(在这种情况下是第二个链承诺的失败案例)

2 个答案:

答案 0 :(得分:1)

这是$q的设计选择,在某种意义上非常不正统。

$q中做出了一项设计决定,throwreject被区别对待,因为图书馆没有跟踪未经处理的拒绝。这是为了避免吞下错误的情况:

JSNO.parse("{}"); // note the typo in JSON, in $q, since this is an error
                  // it always gets logged, even if you forgot a `.catch`.
                  // in Q this will get silently ignored unless you put a .done
                  // or a `catch` , bluebird will correctly track unhandled
                  // rejections for you so it's the best in both.

他们被抓住,处理但仍然被记录。

$q中,使用拒绝:

return $q.reject(new Error("failed with: " + reason));

答案 1 :(得分:0)

你现在可能已经找到了。如果你想将promises与失败联系起来,只需在链的末尾提供失败处理程序。

    promise.then(function(result) {
        console.log("success pass 1 - " + result);
        return result;
    } /* don't handle failure here. Otherwise, a
         new promise (created by 'then') wraps the
         return value (normally undefined) in a new
         promise, and it immediately solves it 
         (means success) since the return value of
         your failure handler is not a promise.

         leave failure handler empty, 'then' will pass
         the original promise to next stage if the
         original promise fails. */
    ).
    then(function(result) {
        console.log("2nd success! result: ", result);
    }, function(reason) {

        /* both 1st and 2nd failure can be captured here */

        console.log("1st or 2nd failure! reason: ", reason);
    });