jquery在循环中延迟

jquery deferred in for loop

本文关键字:延迟 循环 jquery      更新时间:2023-12-27

所以我一直在处理jquery deferred,但在循环中检索数据时遇到了问题。延迟部分似乎只处理来自最终迭代的数据。如果数组中只有一个项目,它也会失败,所以我不确定发生了什么。

我有各种各样的城市名称,我正试图从谷歌地图反向地理编码中获得每个城市的中心坐标

这是我获取中心坐标的函数:

function getGroupLatLng(groupname){
    var deferred = new $.Deferred();
     geocoder.geocode( { 'address': groupname}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
              deferred.resolve(results);
          alert(results[0].geometry.location.lat());
      } else {
      }
    });
    return deferred.promise();
}

这是调用函数的地方,返回结果后会附加一个div:

var newGroupsLength = newGroups.length;
for (i = 0; i < newGroupsLength; i++) {
    newGroups[i]['counter']=counter;
    var locationName = newGroups[i]['name'];
    counter++;
    alert(locationName);
    $.when(getGroupLatLng(locationName)).then(function(results){
        alert("lat = "+results[0].geometry.location.lat());
        var lat=results[0].geometry.location.lat();
        var lng=results[0].geometry.location.lng();
        console.log(newGroups[i]); //this is running the proper number of times, but it logs the results from the final looped item, 'n' number of times. 
        newGroups[i]['lat']=lat;
        newGroups[i]['lng']=lng;
        var jsonArray=[];
        jsonArray = newGroups[i];
        var template = $('#groupsTemplate').html();
        var html = Mustache.to_html(template, jsonArray);
        $('#groups-container').append(html);
    });
}

我遇到的问题是,延迟循环似乎处理for循环中的最后一个项目"n"次,其中"n"是newGroupsLength数组中的项目数。当然,它应该一次性处理每一项。如果删除了延迟操作,则一切正常。

衷心感谢您的帮助。非常感谢

有两个事实协同作用产生了这个结果:

  1. 将对象写入日志时,它是对所写入对象的引用,而不是数据的副本。如果对象在记录后发生更改,则日志将显示更改后的数据。

  2. 在第一次调用then的回调函数之前,循环已经完成。这意味着i对于所有回调都具有相同的值,因此您将所有结果放在同一个对象中。

因此,newGroups[i]中的值将随着处理的每个响应而变化,但您将只看到日志中的最后一个值,因为当日志显示对象时,它就是对象所包含的值。

为了使循环中的每个迭代都保持i的值,以便稍后响应到达时使用IIFE(立即调用的函数表达式)为每个迭代创建一个局部变量:

var newGroupsLength = newGroups.length;
for (i = 0; i < newGroupsLength; i++) {
  (function(i){
    newGroups[i]['counter']=counter;
    var locationName = newGroups[i]['name'];
    counter++;
    alert(locationName);
    $.when(getGroupLatLng(locationName)).then(function(results){
        alert("lat = "+results[0].geometry.location.lat());
        var lat=results[0].geometry.location.lat();
        var lng=results[0].geometry.location.lng();
        newGroups[i]['lat']=lat;
        newGroups[i]['lng']=lng;
        console.log(newGroups[i]); // log the object after setting the values
        var jsonArray=[];
        jsonArray = newGroups[i];
        var template = $('#groupsTemplate').html();
        var html = Mustache.to_html(template, jsonArray);
        $('#groups-container').append(html);
    });
  })(i);
}