jQuery使用.when并推送一个数组

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)

Jon*_*Jon 5

你没有$.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)

这里有几点需要注意:

  1. 返回一组独立的promises意味着你不能$.when直接将它们提供给它,因为该函数被设计为接受多个单独的promises而不是数组; 你需要apply用来补偿.
  2. 我已经移动了arrayLocationclick事件处理程序内部的声明,以便每次单击按钮时都会重置它.每次单击后再次添加结果的问题是由于此数组未被重置.
  3. 最终的处理程序不接受任何参数.那是因为将传递的参数是表示各个AJAX请求的jqXHR对象,这些对象并不实用.而不是arrayLocation通过闭包捕获它,因为你独立地知道结果将存储在那里.