一直在考虑使用ajax()
获取$.when
个回复的回调我仍然不确定这是如何完全有效的,但这是我希望以下做的事情。
当用户每行添加一个城镇和国家/地区时,它会转到.ajax()
中的网址我收到回复并推送该数组以便在.each()
循环之外使用。
目前您将在 here at jsbin内看到,当首先按下button
时,console.log中的响应为[]
,然后当我再次按下时,地址会显示出来。然后第三次按下将再次添加地址,这不应该发生。
的jQuery
var addresses,town;
var arrayLocation = [];
$('button').click(function(){
addresses = function() {
deferred = new $.Deferred();
var arrayOfLines = $('#gps').val().split('\n');
$.each(arrayOfLines, function(index, item) {
town = item.split(',');
$.ajax({
url: 'http://maps.googleapis.com/maps/api/geocode/json?address='+town[0]+'&sensor=false',
dataType: 'json',
success: function (data) {
add = data.results[0].address_components[0].long_name;
lat = data.results[0].geometry.location.lat;
lng = data.results[0].geometry.location.lng;
arrayLocation.push("['"+add+"', "+lat+", "+lng+"]");
console.log("['"+add+"', "+lat+", "+lng+"]");
}
});
});
return arrayLocation;
};
$.when(addresses()).then(function(arrayLocation){
console.log(arrayLocation);
});
});
答案 0 :(得分:5)
您没有正确使用$.when
。主要问题是addresses
函数返回一个裸数组。确实,当异步操作(AJAX调用集)完成时,将来会填充此数组,但从addresses
调用者的角度来看,这是不可能知道的。因此,来电者完全没有机会对正在完成的操作做出反应。
您通常会将$.ajax
的返回值返回给调用者,有点像这样:
addresses = function() {
return $.ajax({ ... });
};
然后来电者可以
$.when(addresses()).then(function(result) { ... });
在这个特定的例子中,这不是直接可能的,因为有多个AJAX调用,所以你需要某种方法将所有这些调用“组合”到一个包中。有多种方法可以做到这一点,所以这里也有你喜欢的问题。
一种解决方案是使用AJAX承诺数组:
$('button').click(function(){
var arrayLocation = [];
addresses = function() {
var promises = [];
var arrayOfLines = $('#gps').val().split('\n');
$.each(arrayOfLines, function(index, item) {
town = item.split(',');
promises.push($.ajax({
url: 'http://maps.googleapis.com/...',
dataType: 'json',
success: function (data) {
add = data.results[0].address_components[0].long_name;
lat = data.results[0].geometry.location.lat;
lng = data.results[0].geometry.location.lng;
arrayLocation.push("['"+add+"', "+lat+", "+lng+"]");
console.log("['"+add+"', "+lat+", "+lng+"]");
}
}));
});
return promises;
};
$.when.apply($, addresses()).then(function(){
console.log(arrayLocation);
});
});
这里有几点需要注意:
$.when
,因为该函数旨在接受多个单独的承诺而不是数组;您需要使用apply
进行补偿。arrayLocation
的声明,以便每次单击按钮时都会重置它。每次点击后再次添加结果的问题是由于此数组未被重置。arrayLocation
,因为您独立知道结果将存储在那里。答案 1 :(得分:0)
没有共享全局变量的略有不同的方法
$('button').click(function () {
var addresses = function () {
var arrayOfLines = $('#gps').val().split('\n'),
arrayLocation = [];
$.each(arrayOfLines, function (index, item) {
var town = item.split(',');
var xhr = $.ajax({
url: 'http://maps.googleapis.com/maps/api/geocode/json?address=' + $.trim(town[0]) + '&sensor=false',
dataType: 'json'
});
arrayLocation.push(xhr);
});
return $.when.apply($, arrayLocation).then(function () {
return $.map(arguments, function (args) {
if (!$.isArray(args[0].results) || args[0].results.length == 0) {
return undefined;
}
var data = args[0].results[0];
var location = data.geometry.location;
var add = data.address_components[0].long_name;
var lat = location.lat;
var lng = lng;
return "['" + add + "', " + lat + ", " + lng + "]";
});
});
return arrayLocation;
};
addresses().done(function (arrayLocation) {
console.log(arrayLocation)
})
});
演示:Fiddle