让我的AngularJS调用错误

时间:2016-07-01 12:30:52

标签: javascript angularjs

我有一个问题我正在解析一些json文件到一个html页面而Urls在另一个json文件中:我有一个很大的问题,因为没有检测到错误,我得到一个空页面,所以在调试时使用一些警报我发现我的控制器得到一个空列表: 我应该按照警报的顺序接听电话:

 alert(tab[i]+ " 1");
 alert(list+ " 2");
 alert(list+ " 3");

但是我收到了这个订单:

 alert(tab[i]+ " 1");
 alert(list+ " 3");
 alert(list+ " 2");

这是我的代码

app.factory('myapp', ['$http', function($http) {        
  function getLists() {
    $http.get('url').success(function(data) { 
      return data;

      var tab = [];
      for (i = 0; i < (data).length; i++) {
        tab.push(data[i]);
      }
    
      var list = [];
      for(i=0; i<tab.length; i++){
        alert(tab[i]+ " 1");
        
        $http.get(tab[i]).then(function(res) {
          list.push(res.data);
          alert(list+ " 2");
        });
        
        alert(list+" 3");
      }
      
      return list;
    })
  }

  return {
    getLists: getLists
  };
])};
我只使用AngularJS而不是Ajax和jQuery。 我该怎么办?

4 个答案:

答案 0 :(得分:2)

由于您尝试在for循环中进行异步请求,因此异步请求的性质导致返回顺序完全不一致。您必须使用$q之类的内容确保退货订单,这样您就可以按顺序解决承诺。

app.factory('listsFactory', ['$http', '$q', function($http, $q) {
  function getLists() {
    return $http.get('url').success(function(tabs) {
      return $q.all(tabs.map(function(tab) {
        return $http.get(tab)
          .then(function(res) {
            return res.data;
          });
      }));
    })
  }

  return {
    getLists: getLists
  };
}]);

然后,像这样使用getLists

app.controller('myController', ['listsFactory', function(listsFactory) {
  listsFactory.getLists().then(function(lists) {
    // do something with lists
    // $scope.something = lists;
  });
}]);

稍微分解一下:似乎你设置标签的第一个循环是多余的,因为回调arg包含你想要的数据(除非我错过了什么)。所以只需命名arg tabs,然后将一个新的promises数组传递给$q.all并返回。调用getLists时,它将按顺序返回一个包含每个promise值的数组的promise。

阐述success回调arg:

$http.get('url').success(function(data) {
  var tab = [];
  for (i = 0; i < (data).length; i++) {
   tab.push(data[i]);
  }
...

您在此处所做的事情是不必要的,因为您有效地克隆data,以便它是一个新数组,具有相同的值,但命名为tabs。您可以通过命名success回调参数tabs来避免这种情况。这将包含与您的版本相同的完全相同的数据,并且还可以减少冗余。

答案 1 :(得分:0)

由于您的格式化,我不确定所有问题,但似乎您的匿名成功处理程序的第一行返回数据,然后您继续执行可能永远不会执行的for循环,因为您返回了该函数的值。

答案 2 :(得分:0)

alert(tab[i]+ " 1");
alert(list+ " 3");
alert(list+ " 2");

您按照以下顺序获得订单,因为alert(list + " 2")$http回拨函数中是异步的。所以当你回调函数被调用时,它是不能保证的。

然而,只要循环完成,就会执行alert(list + " 3")。即,进行for循环中的异步调用但不回调该函数。

这就是您在alert(list + " 3")之前获得alert(list + " 2")的原因。

app.factory('myapp', ['$http', '$q', function($http, $q) {        
  function getLists() {
    $http.get('url').success(function(data) { 
      return data;

      var tab = [];
      for (i = 0; i < (data).length; i++) {
        tab.push(data[i]);
      }
      var list = [];
      var promises = [];
      for(i=0; i < tab.length; i++){        
        promises.push($http.get(tab[i]));        
      }

      $q.all(promises).then(function(data) {        
        angular.forEach(data, function(value, key) {
          this.push(value);
          alert(list + " 2");
        }, list);
        alert(list + " 3");
      });
      return list;
    })
  }

  return {
      getLists: getLists
  };
])};

答案 3 :(得分:0)

我发现问题的解决方案很简单,我只需要在getLists函数中声明list并在第一个http.get之外添加返回列表:

app.factory('myapp', ['$http', function($http) {        
  function getLists() {
    var list = [];
    $http.get('url').success(function(data) { 
      return data;

      var tab = [];
      for (i = 0; i < (data).length; i++) {
        tab.push(data[i]);
      }
    
      
      for(i=0; i<tab.length; i++){
        alert(tab[i]+ " 1");
        
        $http.get(tab[i]).then(function(res) {
          list.push(res.data);
          alert(list+ " 2");
        });
        
        alert(list+" 3");
      }
      
    
    })
      return list;
  }

  return {
    getLists: getLists
  };
])};