如何将多个onError函数分配给promise(由angular的$ http.post返回)

时间:2015-03-20 06:46:58

标签: javascript angularjs promise angular-promise

我的AngularJS代码需要将多个onSuccessonError函数链接到$http.post

返回的承诺
  var promise = $http.post(url);
     promise
      .then(
          /*success 1*/function () { console.log("success 1"); },
          /*error 1*/function () { console.log("error 1"); })
      .then(
          /*success 2*/function () { console.log("success 2"); },
          /*error 2*/function () { console.log("error 2"); });

上述代码的问题在于它打印error 1>当HTTP响应失败而不是success 2>时error 1 error 2

我对stackoverflow进行了一些研究,发现当您有权访问$q时,您可以$q.reject() error 1 error 2触发$http.post,但在我的情况下我只能可以访问error2()返回的承诺。那我该怎么办?

P.S。当然,我可以从error 1内部调用{{1}},但我想链接它们,因为它看起来更具可读性和可扩展性。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

从成功/错误处理程序返回值(或不返回任何值)将解析链中下一个块的承诺。要传播拒绝,请返回$ q.reject():

var promise = $http.post(url);
 promise
  .then(
      /*success 1*/function () { console.log("success 1"); },
      /*error 1*/function () { console.log("error 1"); return $q.reject();})
  .then(
      /*success 2*/function () { console.log("success 2"); },
      /*error 2*/function () { console.log("error 2"); });

答案 1 :(得分:1)

你的问题源于对promises所启用的一些误解 - 即异步代码组合与try / catch的同步代码组成,并具有适当的异常处理。

我具体提到你的陈述:

  

"但我希望将它们链接起来,因为它看起来更具可读性和可扩展性。"

是链接误解的根源。

如果您的示例是同步的(假设所有异步调用都是阻塞的),这可能是您想要做的:

try {
  var data = $http.post(url); // blocking
  var res1 = doSuccess1(data);
  var ret = doSuccess2(res1);
}
catch(e){
  errorHandler1(e);
  errorHandler2(e);
}

而不是这个:

try {
  try {
    var data = $http.post(url);
    var res1 = doSuccess1(data);
  } catch (e) {
    errorHandler1(e);
    // throw ""; // this is what returning $q.reject would have done - a rethrow
  }
} catch (e) {
    errorHandler2(e);
}
var ret = doSuccess2(res1);

这是你用链接实现的目标。换句话说,try中嵌套的catch / doSuccess2和未处理的例外。

以下是第一种方法的异步并行:

var ret;
$http.post(url)
  .then(function(data){
     var res1 = doSuccess1(data);
     ret = doSuccess2(res1);
  }
  .catch(function(e){ // or .then(null, handler)
     doError1(e);
     doError2(e);
  })

如果其中一个doSuccessN函数也是异步的:

var ret;
$http.post(url)
  .then(doSuccess1Async)
  .then(function(res1){
     ret = doSuccess2(res1);
  }
  .catch(function(e){ // or .then(null, handler)
     doError1(e);
     doError2(e);
  })

答案 2 :(得分:0)

只需将处理程序包装在函数中,即成功/错误处理程序参数:

var promise = $http.post(url);
promise
  .then(function(argX, argY){
      success1(argX, argY);
      success2(argX, argY);
  },
  function(argX, argY){
      error1(argX, argY);
      error2(argX, argY);
  });