Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript setTimeout在同步ajax中无法按预期工作_Javascript_Jquery_Ajax_Google Maps - Fatal编程技术网

Javascript setTimeout在同步ajax中无法按预期工作

Javascript setTimeout在同步ajax中无法按预期工作,javascript,jquery,ajax,google-maps,Javascript,Jquery,Ajax,Google Maps,我有一个函数,它在长度为n的数组中循环并构建工厂时多次被调用,每个工厂都使用同步ajax调用,它查询Google Maps API,因此我需要限制它。我在函数上设置了一个setTimeout(),该函数在5秒钟内调用地理编码,以确保安全,并将该setTimeout嵌套在ajax的done()函数中。问题是超时设置了延迟,然后继续进行下一个ajax调用。然后,第一个地理代码在第一个ajax完成5秒后出现 function Plant(plantName, address, inventory){

我有一个函数,它在长度为n的数组中循环并构建
工厂时多次被调用,每个工厂都使用同步ajax调用,它查询Google Maps API,因此我需要限制它。我在函数上设置了一个
setTimeout()
,该函数在5秒钟内调用地理编码,以确保安全,并将该setTimeout嵌套在ajax的done()函数中。问题是超时设置了延迟,然后继续进行下一个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:超过\u查询\u限制

    • 您可以通过以下方法解决此问题:

      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);
      
      var queue=$({});
      风险值递延=[];
      Plant.prototype.pullCoordinates fromdb=函数(dfd){
      var$this=这个;
      log(“为“+$this.address”拉农场坐标);
      $.ajax({
      类型:“POST”,
      数据:{
      地址:$this.address
      },
      url:“actions/getCoordinates.php”
      }).always(函数(){
      控制台日志(“已发送请求”);
      }).fail(函数(jqXHR、textStatus、errorshown){
      console.log(“失败”);
      console.log(textStatus);
      console.log(错误抛出);
      }).完成(功能(数据){
      log(“得到农场坐标”);
      if(data.numRows){
      $this.latCoord=data.latCoord;
      $this.lngCoord=data.lngCoord;
      }
      否则{
      queue.delay(5000).queue(函数)(下一步){
      $this.pullCoordinatesFromAPI();
      解析();
      next();
      });
      }
      });
      返回1;
      };
      植物变量=[植物,植物,…];
      对于(变量i=0;i

      编辑:添加延迟以查看api的所有调用何时完成。

      异步:false,
      是否真的有必要?请注意,对于同步请求,不推荐使用承诺回调(完成、失败、始终等)。如果希望所有调用都同步运行,只需在不超时的情况下调用函数?在数据库调用后暂停5秒不会改变您的查询。问题是您连续调用
      Plant
      的次数太多了。@epascarello我很困惑。也许我没有完全掌握sync vs async,但我想要的是检查数据库,如果那里没有条目,请转到api,然后一旦访问(从DB或api),启动Plant的下一个构造函数。我认为ajax在默认情况下是异步的,因此可以在后台运行而不冻结JS。我希望它冻结JS,以便在当前调用完成之前不会启动下一个调用。谢谢!我以前从未见过jQuery队列!每次我创建工厂时,它都会从数据库或API中获取值。在我多次调用Plant的代码中,我将这些Plant添加到一个数组FULL_列表中。然后我想通过对各种植物的特性进行数学计算来处理完整的清单。在我的主脚本中,是否可以等到所有这些植物都被完全创建(比如等到队列结束)才能继续?@timolescher您可以使用
      jQuery.Deferred
      ,查看我的更新答案。