jquery推迟for循环 [英] jquery deferred in for loop

查看:119
本文介绍了jquery推迟for循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有各种各样的城市名称,我试图从Google地图中获取每个城市的中心坐标。反向地理编码



 函数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();

$ / code>

这是调用函数的地方,一旦结果添加div返回:

  var newGroupsLength = newGroups.length; 

for(i = 0; 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]); //这是运行正确的次数,但它记录了最终循环条目的结果,'n'次数。

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. 循环将在然后被称为第一次。这意味着 i 对于所有回调都具有相同的值,因此您将所有结果放在同一个对象中。


  3. ol>

    因此,对于每个处理的响应, newGroups [i] 中的值都会更改,但您只能看到日志中的最后一个值,因为这就是日志显示时对象所包含的内容。



    为了使循环中的每次迭代保持

      var newGroupsLength = newGroups.length; (i = 0; i  
    (函数(i){

    newGroups [i] [' (位置名称);
    var(位置名称);
    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]); //设置值后记录对象

    var jsonArray = [] ;
    jsonArray = newGroups [i];
    var template = $('#groupsTemplate')。html();
    var html = Mustache.to_html(template,jsonArray);
    $('#groups-container')。append(html);
    });

    })(i);

    }


    So I have been working on jquery deferred but am having trouble when retrieving data in a loop. The deferred portion seems to only process the data from the final iteration. If there is only one item in the array, it fails as well, so I am not sure what is going on.

    I have various city names, and I am trying to get central coordinates for each city from the google maps reverse geocoded

    Here is my function that gets the central coordinates:

    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();
    }
    

    This is where the function is called, and a div is appended once the result is returned:

    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);
        });
    }
    

    The problem I am having is that the deferred loop seems to process the last item in the for loop 'n' number of times, with 'n' being the number of items in the newGroupsLength array. Of course it should process each item one time. If the deferred action is removed, it all works fine.

    Sincere thanks for any help. It is greatly appreciated

    解决方案

    There is two facts that cooperate to give that result:

    1. When writing an object to the log, it's the reference to the object that is written, not a copy of the data. If the object changes after being logged, the log will show the changed data.

    2. The loop will already have completed before the callback function for then is called the first time. That means that i will have the same value for all callbacks, so you put all results in the same object.

    So, the values in newGroups[i] will change for each response that is handled, but you will only see the last values in the log because that's what the object contains by the time the log shows it.

    To make each iteration in the loop keep the value of i for later when the response arrives, you can use an IIFE (immediately-invoked function expression) to create a local variable for each iteration:

    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);
    
    }
    

    这篇关于jquery推迟for循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆