setTimeout与同步ajax无法正常工作

时间:2014-10-28 17:54:53

标签: javascript jquery ajax google-maps

我有一个函数,由于循环遍历长度为n的数组并构造Plants每个使用同步ajax调用而被多次调用,并且它查询Google Maps API所以我需要调整它。我在调用地理编码的函数上设置setTimeout()是安全的,并且在ajax的done()函数中嵌套了setTimeout。问题是超时正在设置延迟,然后继续进行下一个ajax调用。然后在第一个ajax完成后5秒发生第一个地理编码。

function Plant(plantName, address, inventory){
    this.plantName = plantName;
    this.address = address;
    this.inventory = inventory;
    this.latCoord = 0;
    this.lngCoord = 0;

    this.pullCoordinatesFromDB();
}

Plant.prototype.pullCoordinatesFromDB = function(){
    var $this = this;
    console.log("pulling farm coords for: "+$this.address);
    $.ajax({
        async: false,
        type: "POST",
        data: {
            address: $this.address
        },
        url: "actions/getCoordinates.php"
    }).always(function(){
        console.log("request sent");
    }).fail(function(jqXHR, textStatus, errorThrown){
        console.log("failed");
        console.log(textStatus);
        console.log(errorThrown);
    }).done(function(data){
        console.log("got farm coords");
        if(data.numRows){
            $this.latCoord = data.latCoord;
            $this.lngCoord = data.lngCoord;
        }
        else{
            setTimeout( $this.pullCoordinatesFromAPI , 5000);
        }
    });
    return 1;
};

Plant.prototype.pullCoordinatesFromAPI = function(){
    var $this = this;
    GEOCODER.geocode( {'address': $this.address}, function(results, status){
        if (status == google.maps.GeocoderStatus.OK) {
            var location = results[0].geometry.location;
            $this.latCoord = location.lat;
            $this.lngCoord = location.lng;
                console.log("pushing");
            $this.pushCoordinatesToDB();
        }
        else{
            console.log("Could not successfully query the API: "+status);
        }
    });
    return 1;
};

输出似乎是将输出记录为:

  • 拉农场电缆:
  • 请求已发送
  • 获得农场协调
  • 拉农场电缆:
  • 请求已发送
  • 获得农场协调
  • ...
  • 拉农场电缆:
  • 请求已发送
  • 获得农场协调
  • 绘制
  • 无法成功查询API:OVER_QUERY_LIMITS
  • ......

1 个答案:

答案 0 :(得分:1)

您可以使用jQuery.queue()解决此问题,以下是您可以执行此操作的方法:

var queue = $({});
var deferreds = [];

Plant.prototype.pullCoordinatesFromDB = function(dfd){
    var $this = this;
    console.log("pulling farm coords for: "+$this.address);
    $.ajax({
        type: "POST",
        data: {
            address: $this.address
        },
        url: "actions/getCoordinates.php"
    }).always(function(){
        console.log("request sent");
    }).fail(function(jqXHR, textStatus, errorThrown){
        console.log("failed");
        console.log(textStatus);
        console.log(errorThrown);
    }).done(function(data){
        console.log("got farm coords");
        if(data.numRows){
            $this.latCoord = data.latCoord;
            $this.lngCoord = data.lngCoord;
        }
        else{
            queue.delay(5000).queue(function(next){
                $this.pullCoordinatesFromAPI();
                dfd.resolve();
                next();
            });
        }
    });
    return 1;
};

var plants = [Plant, Plant, ...];
for(var i = 0; i < plants.length; ++i){
    var dfd = new $.Deferred();
    plants[i].pullCoordinatesFromDB();
    deferreds.push(dfd);
}

$.when.apply(null, deferreds).done(YOUR_CALLBACK_FUNCTION);

编辑:添加延迟以查看来自api的所有呼叫何时完成。

相关问题