使用$ http调用循环检查异步值

时间:2017-10-16 09:24:50

标签: angularjs asynchronous

在我的网页上,我有一种输入内容,其中包含网址

<div ng-repeat="parent in parents">
   <input ng-model="parent.url" type="text" /> 
</div>
<button ng-click="addParent()"> Add new link </button>

稍后我有一个带 ng-click 的按钮调用我的控制器中的一个函数,如果存在包含这些URL的页面,则会检查(异步)其他(同步)检查。

不知何故,我需要等待处理结果,收集它们,然后根据这些结果显示一些内容。我尝试循环遍历每个网址的所有 $ http 调用:

var results = [];
for (let i = 0; i < parents.length; i++) {
  let p = parents[i];
  $http.get(p.url).
  then((res) => { // pages exists
    results.push(true);
  }, (err) => { // page doesn't exist
    results.push(false);
  });
}

但是这会返回一个空列表,因为$ http调用是异步的。然后我无法真正检查我的所有结果:

if(sync_values){ // this is fine
  if(async_values){ // this is never filled in
    // do something
  }
}

如何在所有$ http通话后检查我的结果?

<小时/> 的更新:

我试图用$q.all()实现一个收集承诺并解决它们的工厂。棘手的一点是解决价值而不是承诺;我需要知道哪些页面存在以及哪些页面丢失了。所以我设法为我的工厂提出以下代码:

let deferred = $q.defer();
let promises = []; 
angular.forEach(parents, function(parent) { 
  promises.push( $http.get(parent.url).then((res) => {
    return true;
  }, (err) => {
    return false;
  }) );
});

$q.all(promises).
then((res) => {
  deferred.resolve(res);
});
return deferred.promise;

现在我返回一个布尔值列表(我知道哪些页面存在,哪些页面不存在)。

1 个答案:

答案 0 :(得分:2)

您应该使用$q

&#13;
&#13;
angular.module('app', [])
.controller('ctrl', ['$q', '$scope', '$http', function($q, $scope, $http){

  $scope.handler = function(){              
     $scope.results = [];
     $scope.loaded = false;
     $scope.parents = [1,2,3,4,5,6,7,8,9,10];
     var promises = [];

     for (var parent in $scope.parents) {        
       let deffered = $q.defer();	  	 
       promises.push(deffered.promise);
       $http.get('https://stackoverflow.com').
         then(res => {  
           console.log('true');
           $scope.results.push(true);
           deffered.resolve(true);
         }, err => {          
           console.log('false');
           $scope.results.push(false);
           deffered.resolve(false);
         });
      }

      $q.all(promises).then(() => {
         console.log('completed');			
         $scope.loaded = true;
      });	  
    }
}])
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app='app' ng-controller='ctrl'>
  <input type='button' value='Click' ng-click='handler()'/>
  <div ng-if='loaded'>
    <span ng-repeat='result in results track by $index'>{{result}} </span>
  </div>    
</div>
&#13;
&#13;
&#13;