ngp*_*und 0 javascript ajax jquery asynchronous .when
我一直在考虑ajax()使用回调获取回复,$.when我仍然不确定这是如何完全有效的,但这是我想要的以下内容.
当用户每行添加一个城镇和国家时,它会转到.ajax()我得到响应的url中,并且它会推动数组在.each()循环之外可用.
此刻你会在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);
});
});
Run Code Online (Sandbox Code Playgroud)
你没有$.when正确使用.主要问题是该addresses函数返回一个裸数组.确实,当异步操作(AJAX调用集)完成时,将来会填充此数组,但从addresses调用者的角度来看,这是不可能知道的.因此,呼叫者完全没有机会对正在完成的操作作出反应.
你通常会做的是返回$.ajax调用者的返回值,有点像这样:
addresses = function() {
return $.ajax({ ... });
};
Run Code Online (Sandbox Code Playgroud)
然后呼叫者可以这样做
$.when(addresses()).then(function(result) { ... });
Run Code Online (Sandbox Code Playgroud)
在这个特定的例子中,这不是直接可能的,因为有多个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);
});
});
Run Code Online (Sandbox Code Playgroud)
这里有几点需要注意:
$.when直接将它们提供给它,因为该函数被设计为接受多个单独的promises而不是数组; 你需要apply用来补偿.arrayLocationclick事件处理程序内部的声明,以便每次单击按钮时都会重置它.每次单击后再次添加结果的问题是由于此数组未被重置.arrayLocation通过闭包捕获它,因为你独立地知道结果将存储在那里.