AngularJS:Chaining promises忽略拒绝

时间:2014-04-17 20:53:56

标签: angularjs http chaining q

我是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;

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

例如,如果第二次操作失败,则应抛出错误"某些数据错误"。

谢谢

2 个答案:

答案 0 :(得分:1)

在我看来,只有当您的错误条件触发时(即results.status不是“ok”),您才会遇到问题,因为在这种情况下您不会返回任何内容。当你没有返回任何东西时,Q将回退到当前的promise(由最后一个函数返回),并且当它成功时,也将调用下一个方法(因为它被挂钩的promise已经完成)。以下是如何使用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

答案 1 :(得分:0)

只是简单地看一下你的代码,似乎根本没有任何理由使用$ q(好吧它会被间接使用。

  // 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'); 
  });

因为承诺更像是try-catch块,而不是人们可能会想到的,当你处理错误时,但是不要在处理程序中抛出另一个,你实际上说你已经恢复了(这不是你的意图)... < / p>

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

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;
  //}

  );
});