Chain Angular $ http可以正常调用吗?

时间:2015-09-13 04:19:18

标签: angularjs angular-promise

我一直在阅读关于$ q和承诺的几天,我似乎也明白了......我在实践中遇到以下情况:

  1. 发出$ http请求并检查是否可以进行后续调用。
  2. 如果第一次呼叫失败,则返回“无数据”,如果成功并说可以进行呼叫,则进行第二次呼叫,如果不​​是 - 再次“无数据”。如果第二次调用成功,则返回数据,如果不是 - “无数据”。它看起来像这样(大约,我简化了一般的想法,所以不要担心这里的小错误):

            return $http.get (something)
                .then(function(allowedAccess){
                    if(allowedAccess){
                        return $http.get (somethingElse)
                            .then( function(result){return {data:result} },
                            function(error){return {data:"n0pe"} }
                        )
                    } else {
                        return {data:"n0pe"}
                    }
                },
                function(){ return {data:"n0pe"} });
    
  3. 我被告知在这里使用$ q。我真的不明白我会怎样或为什么。 $ http电话已经是承诺。

    如果有办法让这个更清洁,我看不到它。刚刚完成重新阅读post on the subject。基本上,我错过了什么/有更好的方法吗?

    编辑:也只是重新阅读a tutorial on chaining promises - 它根本不处理呼叫失败。基本上将此作为尽职调查发布。

    编辑2:这是关于我所询问的理论的详细说明,摘自第一篇文章:

      

    这是一个简单的例子。如果你的then()回调返回另一个promise,它会变得非常强大。在这种情况下,下一个then()只会在承诺结算后执行。例如,此模式可用于串行HTTP请求(请求取决于前一个请求的结果):

    这似乎是在谈论像这样的链:

       asyncFn1(1)
        .then(function(data){return asyncFn2(data)})
        .then(function(data){return asyncFn3(data)})
    

    所以,如果我理解正确的话a)。不适用于我,因为我没有第三功能。 B)。如果我有三个函数会适用于我,因为当我在第一个$ http请求中运行if语句时,只有在if语句中我才会返回另一个promise。所以,理论上,如果我有三个异步函数来链接,我需要将我的if语句放在一个promise中吗?

2 个答案:

答案 0 :(得分:13)

Promise确实有助于进行异步调用的代码组合。换句话说,它们允许您以与编写同步调用集的方式类似的方式编写代码(使用链式.then),并且好像同步代码位于{{ 1}} / try阻止(带catch)。

所以,想象一下你的HTTP调用是阻塞的 - 你的逻辑就是这样:

.catch

你可以稍微简化一下:

var allowedAccess, data;
try {
  allowedAccess = $http.get(something);

  if (allowedAccess){
    try{
      var result = $http.get(somethingElse);
      data = {data: result};
    } catch (){
      data = {data: "n0pe"};
    }
  } else {
    data = {data: "n0pe"};
  }
} catch (){
  data = {data: "n0pe"};
}
return data;

这将转换为异步版本:

var allowedAccess, result;
try {
  allowedAccess = $http.get(something);
  var result;
  if (allowedAccess) {
     result = $http.get(somethingElse);
  } else {
     throw;
  }
  data = {data: result};
} catch () {
   data = {data: "n0pe"};
}
return data;

至少,这是在使用分支和异步调用编写代码时可以应用的原因。

我并不是说我提供的版本是最佳的或更短的 - ,但是,由于单个错误处理,更多的DRY。但只是意识到当你执行return $http .get(something) .then(function(allowedAccess){ if (allowedAccess){ return $http.get(somethingElse); } else { return $q.reject(); // this is the "throw;" from above } }) .then(function(result){ return {data: result}; }) .catch(function(){ return {data: "n0pe"}; }) 时,它相当于.then(success, error) / try,而不是之前的异步操作 - 根据您的具体情况,这可能需要也可能不需要。

答案 1 :(得分:-2)

$ q将有助于减少这样的调用金字塔:

async-call1.then(...
  aysnc-call2.then(...

此博客文章 - http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/ - 提供了一种制作多个HTTP请求的简洁方法。注意使用$ q的清洁方法。如果您遇到单个HTTP端点,使用您的方法就可以了。我说,你所拥有的也很好; $ q可能会在未来提供更大的灵活性。

博客文章描述了使用$ q时的服务,代码看起来更干净。

service('asyncService', function($http, $q) {
  return {
    loadDataFromUrls: function(urls) {
      var deferred = $q.defer();
      var urlCalls = [];
      angular.forEach(urls, function(url) {
        urlCalls.push($http.get(url.url));
      });
      // they may, in fact, all be done, but this
      // executes the callbacks in then, once they are
      // completely finished.
      $q.all(urlCalls)
      .then(...

我也是承诺的初学者,所以带着一点点盐。