jquery 在 for 循环中延迟
jquery deferred in for loop
所以我一直在研究 jquery deferred 但在循环中检索数据时遇到问题。延迟部分似乎只处理来自最终迭代的数据。如果数组中只有一项,它也会失败,所以我不确定发生了什么。
我有多个城市名称,我正在尝试从 google 地图反向地理编码
中获取每个城市的中心坐标
这是我获取中心坐标的函数:
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 数组中的项数。当然,它应该对每个项目进行一次处理。如果删除延迟操作,一切正常。
衷心感谢您的帮助。非常感谢
有两个事实共同作用得出该结果:
将对象写入日志时,写入的是对对象的引用,而不是数据的副本。如果对象在记录后发生变化,日志将显示变化的数据。
在第一次调用 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);
}
所以我一直在研究 jquery deferred 但在循环中检索数据时遇到问题。延迟部分似乎只处理来自最终迭代的数据。如果数组中只有一项,它也会失败,所以我不确定发生了什么。
我有多个城市名称,我正在尝试从 google 地图反向地理编码
中获取每个城市的中心坐标这是我获取中心坐标的函数:
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 数组中的项数。当然,它应该对每个项目进行一次处理。如果删除延迟操作,一切正常。
衷心感谢您的帮助。非常感谢
有两个事实共同作用得出该结果:
将对象写入日志时,写入的是对对象的引用,而不是数据的副本。如果对象在记录后发生变化,日志将显示变化的数据。
在第一次调用
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);
}