Angular 解决主承诺被拒绝时由 "then" 函数返回的承诺

Angular resolves the promise returned by "then" function when the main promise is rejected

谁能解释一下为什么 then 函数返回的第二个 promise 被解决了?它看起来像 Angular Promises 实现中的 JS 错误。根据文档 here 第二个承诺也应该被拒绝。

// Code goes here
var myMod = angular.module("myMod", []);
myMod.controller('bodyCtrl', function($scope, $timeout, $q) {
    var deferred = $q.defer();
    deferred.promise.then(function(d) {
      console.log("success called");
      return d;
    }, function(d) {
      console.log("failure called");
      return d;
    })
    .then(function(d) {
      console.log("success called2");
      return d;
    }, function(d) {
      console.log("failure called2");
      return d;
    });
    
    $timeout(function() {
      deferred.reject();
    }, 2 * 1000);
});
<!DOCTYPE html>
<html ng-app="myMod">

  <head>
    <script src="https://code.angularjs.org/1.5.8/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="bodyCtrl">
    <h1>Hello Plunker!</h1>
  </body>

</html>

这是设计使然。发生这种情况是因为通过为 promise 提供 errorCallback,您实际上是 handling/resolving/catching 拒绝(就像您在 try...catch 块中捕获异常一样)。如果您删除第一个 errorCallback 函数,您应该会在开发人员控制台中看到 failure called2,或者如果您在第一个回调中抛出新的异常。

正如 @Nikolaj Dam Larsen@georgeawg 所说,你的问题是在你的 errorCallback() 中你没有抛出例外。请参阅以下示例 (PLUNKER)...

function bodyCtrl($timeout, $q){
    deferred.promise
    .then(function(d) { //Promise 1
        console.log("success called");
        return d;
    }, function(e) {
        console.log("failure called");
        throw e; //Throw instead return
    })
    .then(function(d) { //Promise 2
        console.log("success called2");
        return d;
    }, function(e) {
        console.log("failure called2");
        throw e; //Throw instead return
    });

    $timeout(function() {
        deferred.reject("Custom Rejected: " + new Date());
    }, 2000);
}