【问题标题】:AngularJS: Chaining promises ignore rejectionAngularJS:链接承诺忽略拒绝
【发布时间】:2014-04-17 20:53:55
【问题描述】:

我是 AngularJS 的新手,我想知道为什么 AngularJS 会继续进行下一个链接操作,即使我之前的一个链接函数失败了。

  // Manipulate data
  function manipulationData(data) {
    return data.total + 2;
  }

  /*
  * Begin chaining promises
  */
  var deferred = $q.defer();

  // JSON Request
  $http.get('/json_test.json')

  // If results is ok, then manipulate some data
  .then(function(results) {
    if(results.status == "ok") {
      return manipulationData(results);
    } else {
      deferred.reject("Some data error");
    }
  }, function(reason) {
    deferred.reject("Error request: " + reason);
  })

  // If manipulation is success
  .then(function(results) {
    if(results > 5) {
      return $http.get('http://host.com/second');
    } else {
      deferred.reject("Error! Data is invalid");
    }
  }, function(reason) {
    deferred.reject("Error request: " + reason);
  })

  .then(function(result){
    return $http.get('http://host.com/second'); 
  })
  return deferred.promise;

由于某种原因,即使其中一个功能失败,应用程序也会继续执行所有功能。我希望在第一个承诺不起作用时停止操作。

例如,如果第二次操作失败,它应该抛出错误“一些数据错误”。

谢谢

【问题讨论】:

    标签: angularjs http chaining q


    【解决方案1】:

    在我看来,只有当您的错误条件触发(即 results.status 不是“ok”)时,您才会遇到问题,因为在这种情况下您不会返回任何内容。当你不返回任何东西时,Q 将回退到当前的承诺(由最后一个函数返回)并且当它成功时,下一个方法也将被调用(因为它被挂钩的承诺被履行)。这是一个如何使用 Q 处理自定义错误的示例:

    promise.then(function(data) {
        if (p(data)) {
            return doSomethingAsync(data);
        } else {
            return $q.reject("Some error...")
        }
    }).then(function(data) {
        doSomething(data); // This will be called only if p(data) was true.
    }).catch(function(err) {
        console.log(err); // This will be called only if p(data) was false.
    })
    

    $q 是一个普通的 AngularJS 服务,所以你只需要将它作为参数添加。您也可以参考文档页面 - https://code.angularjs.org/1.2.12/docs/api/ng.$http

    【讨论】:

      【解决方案2】:

      简单地看一下你的代码,似乎没有任何理由使用 $q (嗯,它会间接使用 ofc。

        // Manipulate data
        function manipulationData(data) {
          return data.total + 2;
        }
      
      
        // JSON Request
        return $http.get('/json_test.json')
      
        // If results is ok, then manipulate some data
        .then(function(results) {
          if(results.status == "ok") {
            return manipulationData(results);
          } else {
            throw new Error("Some data error");
          }
        }, function(reason) {
          throw new Error("Error request: " + reason);
        })
      
        // If manipulation is success
        .then(function(results) {
          if(results > 5) {
            return $http.get('http://host.com/second');
          } else {
            throw new Error("Error! Data is invalid");
          }
        }, function(reason) {
          //Note: This will give 'Error request: Error request: {reason}' 
          //      in cases where '/json_test.json' failed
          throw new Error("Error request: " + reason);
        })
      
        .then(function(result){
          return $http.get('http://host.com/second'); 
        });
      

      由于 promise 的工作方式比人们想象的更像 try - catch 块,当您处理错误但不要在处理程序中抛出另一个错误时,您实际上是在说您已经恢复(这不是您的意图)...

      这是一个 plunk,如果您删除第一个被注释掉的代码块,您可以在其中看到效果。

      http://plnkr.co/edit/kegH8Ca3O3EjQqGCi143?p=preview

      angular.forEach(self.stages, function(stage) {
        promise = promise.then(function() {
          stage.state = 'progress';
          return $timeout(function() {
            stage.state = 'done';
            if(stage.id == 3) throw Error("Test");
          }, 1000, true);
        }
      
        // add this code to see that we recover.
        //, function(error) {
        //  stage.state = 'error';
        //}
      
      
        // add this code to see how we re-throw the error
        //, function(error) {
        //  stage.state = 'error';
        //  throw error;
        //}
      
        );
      });
      

      【讨论】:

        猜你喜欢
        • 2013-09-16
        • 1970-01-01
        • 2019-11-25
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 2021-05-31
        • 2013-11-04
        • 1970-01-01
        相关资源
        最近更新 更多