看看这个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
来达到连续的错误情况(在这种情况下是第二个链承诺的失败案例)
答案 0 :(得分:1)
这是$q
的设计选择,在某种意义上非常不正统。
在$q
中做出了一项设计决定,throw
和reject
被区别对待,因为图书馆没有跟踪未经处理的拒绝。这是为了避免吞下错误的情况:
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)
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);
});