Javascript 在有序的对象数组上处理多个AJAX或SOAP调用

Javascript 在有序的对象数组上处理多个AJAX或SOAP调用,javascript,ajax,Javascript,Ajax,每个对象都必须在级联中触发多个AJAX调用(每个请求都在前面的回调中调用),但这里的顺序很重要。第一个对象必须在下一个对象开始其请求之前完成所有请求,依此类推 实际上,在我的代码中,所有对象都在同时处理它们的请求,即使我在waitForProcessFinish()函数中使用了超时 //object properties function LayerQuery(objectDefinition) { this.class = "FilteredLayer"; this.alias

每个对象都必须在级联中触发多个AJAX调用(每个请求都在前面的回调中调用),但这里的顺序很重要。第一个对象必须在下一个对象开始其请求之前完成所有请求,依此类推

实际上,在我的代码中,所有对象都在同时处理它们的请求,即使我在waitForProcessFinish()函数中使用了超时

//object properties
function LayerQuery(objectDefinition) {
    this.class = "FilteredLayer";
    this.alias = objectDefinition["alias"];
    this.sourceLayerName = objectDefinition["sourceLayerName"];
    this.sourceTableName = objectDefinition["sourceTableName"];
    this.fieldName = objectDefinition["fieldName"];
    this.operator = objectDefinition["operator"];
    this.label = objectDefinition["label"];
    this.layerStyle = objectDefinition["layerStyle"];
    this.value = objectDefinition["value"];
    this.layerVisible = objectDefinition["layerVisible"];
    this.labelVisible = objectDefinition["labelVisible"];
    this.zoomMin = objectDefinition["zoomMin"];
    this.zoomMax = objectDefinition["zoomMax"];
    this.position = objectDefinition["position"];
    this.control = objectDefinition["control"];
    this.info = objectDefinition["info"];
    this.fieldsOrder = objectDefinition["fieldsOrder"];
    this.fields = [];
    this.baseLayer = objectDefinition["baseLayer"];
}

function LayerQueries(list) {
  this.queries = list;
}

LayerQueries.prototype.loadLayers = function(){
  for (i=0; i< this.queries.length; i++){
      this.queries[i].loading = true;
      this.queries[i].addFilteredLayer();
      this.queries[i].waitForProcessFinish(); //wait for object's requests done to start next object
  }
  this.waitForProcessesFinish(); // wait for all objects' requests done
}

LayerQuery.prototype.addFilteredLayer = function(){
  var query = this;
  $.soap({
  url: 'https://carto48dev.mels.gouv.qc.ca/pushnsee_4.8/services/MapService',
  method: 'addFilteredLayer',
  appendMethodToURL: false,
  data : {
      mapInstanceKey: mapKey,
      tablePath: this.sourceTableName,
      layerName: this.sourceLayerName,
      separators: { value: ["AND"]},
      fieldNames: { value: [this.fieldName]},
      operators: { value: [this.operator]},
      values: { value: [this.value]},
      int: 0
      },
  error: function(e){
      console.log("Error addFilteredLayer: " + query.sourceLayerName);
      query.loading = false;
   },
  success: function(soapResponse){
     query.getColumnDefinitions();
  }
  });
}

LayerQuery.prototype.getColumnDefinitions = function(){
  var query = this;
  $.soap({
    url: 'https://carto48dev.mels.gouv.qc.ca/pushnsee_4.8/services/GeobaseService',
    method: 'getColumnDefinitions',
    appendMethodToURL: false,
    data : {
      tablePath: this.sourceTableName,
    },
    error: function(e){
        console.log("Error getColumnDefinitions: " + query.sourceLayerName);
        query.loading = false;
     },
    success: function(soapResponse){
      var columnsDef = JSON.parse(soapResponse.toJSON().Body.getColumnDefinitionsResponse.getColumnDefinitionsReturn.text);
      for (var i=0; i< columnsDef.length; i++){
        query.fields.push(columnsDef[i].name);
      }
      query.loading = false;
    }
  });
}

LayerQuery.prototype.waitForProcessFinish = function(){
  query = this;
  if (this.loading == false) {
    console.log("process finish")
    return;
  }else {
    setTimeout(function(){
       console.log("waiting...");
       query.waitForProcessFinish();
    },100);
  }
}

LayerQueries.prototype.waitForProcessesFinish = function(){
  layerQueries = this;
  this.processesFinished = 0;
  for (i=0; i<this.queries.length; i++){
    if (this.queries[i].loading == false) {
      this.processesFinished += 1;
    }
  }
  if (this.processesFinished == this.queries.length){
    layerQueries.setVisibilities();
  } else {
    setTimeout(function(){
       console.log("waiting again...");
       layerQueries.waitForProcessesFinish();
    },100);
  }
}

var queries = new LayerQueries([Mask_General_Query,Mask_Query,Cs_General_Query,Cs_Query,Mrc_General_Query,Mrc_Query,Mun_General_Query,Mun_Query,Org_FpAdulte_Query,Org_Sec_Query,Org_PrimSec_Query,Org_Primaire_Query]);

queries.loadLayers(); //trigger the ajax requests
//对象属性
功能层查询(objectDefinition){
this.class=“FilteredLayer”;
this.alias=objectDefinition[“alias”];
this.sourceLayerName=objectDefinition[“sourceLayerName”];
this.sourceTableName=objectDefinition[“sourceTableName”];
this.fieldName=objectDefinition[“fieldName”];
this.operator=objectDefinition[“operator”];
this.label=objectDefinition[“label”];
this.layerStyle=objectDefinition[“layerStyle”];
this.value=objectDefinition[“value”];
this.layerVisible=对象定义[“layerVisible”];
this.labelVisible=objectDefinition[“labelVisible”];
this.zoomMin=objectDefinition[“zoomMin”];
this.zoomMax=objectDefinition[“zoomMax”];
this.position=objectDefinition[“position”];
this.control=objectDefinition[“control”];
this.info=objectDefinition[“info”];
this.fieldsOrder=objectDefinition[“fieldsOrder”];
this.fields=[];
this.baseLayer=objectDefinition[“baseLayer”];
}
功能层查询(列表){
this.querys=列表;
}
LayerQueries.prototype.loadLayers=函数(){
对于(i=0;ifor(i=0;i
setTimeout
不阻塞-它将其参数函数安排为稍后执行,并立即返回。因此,当调用
waitForProcessFinish
时,无论发生什么情况,它都会立即返回-因此在第一个AJAX完成之前发送下一个AJAX

相反,您可以将函数调用链接为回调:

LayerQueries.prototype.loadLayers = function(){
  var layerQueries = this;
  var list = this.queries;
  if (list.length > 0){
      list[0].addFilteredLayer(makeCallback(1));
  }
  function makeCallback(i){
      if (i < list.length){
         return function() { list[i].addFilteredLayer(makeCallback(i+1)); }
      } else {
         return function() { layerQueries.setVisibilities(); }
      }
  }
}

LayerQuery.prototype.addFilteredLayer = function(callback){
    // ...
    // ...
    // ...
  success: function(soapResponse){
     query.getColumnDefinitions(callback);
  }
  });
}

LayerQuery.prototype.getColumnDefinitions = function(callback){
    // ...
    // ...
    // ...
    success: function(soapResponse){
      var columnsDef = JSON.parse(soapResponse.toJSON().Body.getColumnDefinitionsResponse.getColumnDefinitionsReturn.text);
      for (var i=0; i< columnsDef.length; i++){
        query.fields.push(columnsDef[i].name);
      }
      callback();
    }
  });
}
LayerQueries.prototype.loadLayers=function(){
var layerQueries=此;
var list=this.querys;
如果(list.length>0){
列表[0]。addFilteredLayer(makeCallback(1));
}
函数makeCallback(i){
如果(i
i不确定是否理解,
callback()不在任何地方定义“回调”是一个函数,由loadLayers作为参数传递给addFilteredLayer,然后由addFilteredLayer传递给getColumnDefinitions。请注意这些函数的标题行中的新参数。这工作得很好,谢谢,但是当我放置
callback()时,出现了一些奇怪的现象。如果其中3个对象针对特定AJAX请求返回错误,那么对于第三个对象,我在控制台中得到一个错误:TypeError:
回调不是函数
事实上,调用callback()时,列表中最后一个得到回调的对象不是函数错误在流程结束时,由于调用loadLayers时没有给出参数,所以发生了这种情况—它希望在所有AJAX请求完成后调用函数。我已经修改过了,所以它不再需要这个了