为什么 $q.when 后跟 $q.reject in Angular.js 会成功?

Why does $q.when followed by $q.reject in Angular.js result in success?

在Angular.js中使用$q时,为什么这段代码没有:

 $q.when("test")
   .then($q.reject("error"))
   .then(
     function(v) {
       $scope.result = "Success: " + v;
     },
     function(e) {
       $scope.result = "Failure: " + e;
     }
   )

调用错误回调?

在 jsfiddle 中:http://jsfiddle.net/c9tv6kz7/1/

Per the doc

then(successCallback, errorCallback, notifyCallback) – regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason. Additionally, the notify callback may be called zero or more times to provide a progress indication, before the promise is resolved or rejected.

This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining). It also notifies via the return value of the notifyCallback method. The promise cannot be resolved or rejected from the notifyCallback method.

我们真正关心的是

This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback

每次您在 $q.when 上调用 then 时,您都在创建一个新的承诺。即使第一个承诺被拒绝,第二个承诺也没有。第二个没有被拒绝,因为您的 successCallback 和 errorCallback 的 return 值没有拒绝它。

更简单的答案是:

$q.reject("error")

创建一个新的承诺对象,由您的 $q.when().then() 调用。

这真的不会如你所想。 $q.reject("error") returns 具有 then 功能的对象。

查看 docs 中的 方法 部分:

promiseB = promiseA.then(function(result) {
  // success: do something and resolve promiseB
  //          with the old or a new result
  return result;
}, function(reason) {
  // error: handle the error if possible and
  //        resolve promiseB with newPromiseOrValue,
  //        otherwise forward the rejection to promiseB
  if (canHandle(reason)) {
   // handle the error and recover
   return newPromiseOrValue;
  }
  return $q.reject(reason);
});

你看到他们的表现了吗then(function () { return $q.reject(reason); })这与你原来的有很大不同。

查看新内容fiddle

当我这样做时,我解决了一个错误:

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

myApp.controller('MyCtrl', ['$scope', '$q', function($scope, $q) {
  $q.when("test")
    $q.reject('Failed!')
    .then(
      function(v) {
        $scope.result = "Success: " + v;
      },
      function(e) {
        $scope.result = "Failure: " + e;
      }
    )
}]);

http://jsfiddle.net/emporio/67db45f9/3/

如果我删除 $q.reject('Failed!'),它将解析为 .then()。