Javascript 角度传感器中异步事件的故障

Javascript 角度传感器中异步事件的故障,javascript,angularjs,angular-promise,Javascript,Angularjs,Angular Promise,我的代码在一个数组中循环10个项目,对每个项目发出请求,然后将返回的数据推送到一个数组中。一切正常,直到$q.all行 details.getDetails = function(idSet, pageNum) { var page = idSet[pageNum], mainDeferred = $q.defer(), promises = [], combinedItems = []; for(var i=0; i<page.length;

我的代码在一个数组中循环10个项目,对每个项目发出请求,然后将返回的数据推送到一个数组中。一切正常,直到
$q.all

details.getDetails = function(idSet, pageNum) {
  var page = idSet[pageNum],
      mainDeferred = $q.defer(),
      promises = [],
      combinedItems = [];

  for(var i=0; i<page.length; i++){
    var deferred = $q.defer();
    ngGPlacesAPI.placeDetails({placeId: page[i][i]})
      .then(function(data){
        combinedItems.push(data);
        console.log(combinedItems); /// This shows the objects being pushed into the array
        deferred.resolve();
      });

    promises.push(deferred.promise);
  }

  console.log(promises); /// This shows the 10 promises

  $q.all(promises).then(function() { /// Nothing after this line runs
    console.log('test', mainDeferred.promise); /// This logs nothing
    mainDeferred.resolve(combinedItems);
  });
  return mainDeferred.promise;
};
details.getDetails=函数(idSet,pageNum){
var page=idSet[pageNum],
main deferred=$q.deferred(),
承诺=[],
combinedItems=[];

对于(var i=0;i),在javascript中处理异步时,这是一个非常常见的错误

应该问的问题是:“当解析器(您传递给
的函数)查找变量
deferred
,它会返回什么变量?”然后回答是,它们都引用您声明的最后一个
deferred

问题是,您在resolve函数之外声明了
延迟
。还记得javascript是如何查找变量的吗

  • 变量(在我们的例子中是
    延迟的
    )在立即函数范围内可用吗?(在我们的例子中是否)
  • 遍历父作用域,直到找到具有给定名称的变量
  • 当冲突解决程序启动时,您已经重新声明了10次
    deferred
    ,每个声明都会覆盖上一个声明!因此每次冲突解决程序启动时,它实际上都会解析相同的
    deferred

    答案是将您的
    延迟
    声明包装在一个闭包中:

    for(var i=0; i<page.length; i++){
      (function(){
        var deferred = $q.defer();
        ngGPlacesAPI.placeDetails({placeId: page[i][i]})
          .then(function(data){
            combinedItems.push(data);
            console.log(combinedItems); /// This shows the objects being pushed into the array
            deferred.resolve();
          });
        promises.push(deferred.promise);
      })()
    }
    

    摆脱
    延迟
    当然是正确的做法。但是,就我个人而言,我会找到一个普通的循环,你可以将承诺推到一个数组上,传递给
    $q。所有的
    都比
    数组更容易使用。应用
    +
    项。映射你在这里设计的
    解决方案。非常感谢你的详细说明iled答案。这真的帮助我理解和学习了一些新东西。你的第二个解决方案尤其让我的车轮转动,最终让我找到了答案。@mgilson也感谢你帮助我找到了解决方案。我最终像你提到的那样循环,因为我在数组上的索引方面遇到了问题。map@mgilson这可能是一个代码问题我更喜欢函数迭代器,但有些人觉得过程循环更容易理解。每个循环都有自己的风格!
    
    details.getDetails = function(idSet, pageNum) {
      var page = idSet[pageNum];
    
      // generate an array from 0 to page.length
      var items = Array.apply(null, { length: page.length })
    
      var promises = items.map(function (i) {
        return ngGPlacesAPI.placeDetails({placeId: page[i][i]});
      })
    
      return $q.all(promises)
    };