当另一个完成时执行一个 Ajax 请求

Posted

技术标签:

【中文标题】当另一个完成时执行一个 Ajax 请求【英文标题】:Execute an Ajax request when another one is finished 【发布时间】:2017-02-13 15:31:03 【问题描述】:

我正在遍历 Leaflet 地图中的标记层,以捕捉每个标记的纬度和经度,并使用 Ajax 在我的数据库中发送此坐标。

然后,当我发送数据库中每个标记的纬度和经度后,我想用另一个 Ajax 调用我的 WFS 层,以显示添加到我的数据库中的新标记。

为此,我想在第一个 Ajax 完成后调用我的第二个 Ajax,所以我尝试使用 $.when().done(),但它不起作用。

如果我发送几个标记的坐标,它可以工作,但如果我尝试发送 200 个标记,第二个 Ajax 会在第一个结束之前执行,并且不会显示我的 WFS 层。如果我在第二个 Ajax 上设置超时以给第一个 Ajax 执行时间,它可以工作,但这不是解决方案。

这是我的代码:

var dialog_create = $('#dialog_create').dialog();
dialog_create.dialog(options, 
  buttons: 
    Add: function() 
      $.when(
        layer.eachLayer(function(layer) 
          latGPS = layer.getLatLng().lat;
          lngGPS = layer.getLatLng().lng;

          $('#latitudeEP').val(latGPS);
          $('#longitudeEP').val(lngGPS);

          data = $("#formulaireEP").serialize();

          $.ajax(
            url: 'assets/php/create/create_EP.php',
            type: $("#formulaireEP").attr('method'),
            data: data,
            success: function() 
              dialog_create_EP.dialog("close");
              $("#formulaireEP")[0].reset();
            
          )
        )
      ).done(function(data) 
        //setTimeout(function()
        $.ajax(
          url: owsrootUrlAssainissement + L.Util.getParamString(parametersEP),
          dataType: 'jsonp',
          jsonpCallback: 'callEP'
        ).done(EPvannes1);
        //,5000);
      );
      return false;
    ,
    Cancel: function() 
      dialog_create_EP.dialog("close");
    ,
  
);
dialog_create_EP.dialog("open");

编辑:

这是我使用延迟对象的最佳尝试,但它不起作用......

var dialog_create = $('#dialog_create').dialog();
dialog_create.dialog(options, 
  buttons: 
    Add: function() 
    var defer = $.Deferred();

      function getAjaxDeffered()
        layer.eachLayer(function(layer) 
          latGPS = layer.getLatLng().lat;
          lngGPS = layer.getLatLng().lng;

          $('#latitudeEP').val(latGPS);
          $('#longitudeEP').val(lngGPS);

          data = $("#formulaireEP").serialize();

          $.ajax(
            url: 'assets/php/create/create_EP.php',
            type: $("#formulaireEP").attr('method'),
            data: data,
            success: function() 
              dialog_create_EP.dialog("close");
              $("#formulaireEP")[0].reset();
            
          )
        )
      

      defer.resolve(getAjaxDeffered());

      $.when(defer).then(function(data) 
        //setTimeout(function()
        $.ajax(
          url: owsrootUrlAssainissement + L.Util.getParamString(parametersEP),
          dataType: 'jsonp',
          jsonpCallback: 'callEP'
        ).done(EPvannes1);
        //,5000);
      );
      return false;
    ,
    Cancel: function() 
      dialog_create_EP.dialog("close");
    ,
  
);
dialog_create_EP.dialog("open");

【问题讨论】:

这个答案会帮助你***.com/a/39679275/6608101 在first的success函数下执行你的第二个ajax调用 由于我的第一层在 layer.eachLayer 中,我无法在第一个的 sucess 函数下执行第二个 Ajax,否则每次发送标记时都会调用我的第二个 Ajax我猜我的数据库 @Loading.. 谢谢,我认为使用 Defered 对象确实可以解决我的问题。我会看看并尝试了解它是如何工作的:-) @Loading.. 对不起,我已经编辑了我的代码,试图使用一个延迟对象,但它仍然无法正常工作,尽管我认为我使用这种方法很糟糕 【参考方案1】:

好的,感谢这篇文章,我找到了解决方案: jquery deferred in .each loop

这是我的后代的最终代码 ;-) :

var dialog_create = $('#dialog_create').dialog();
dialog_create.dialog(options, 
  buttons: 
    Add: function() 
 
      function getAjaxDeffered()

      var promises = [];

        layer.eachLayer(function(layer) 

        var def = new $.Deferred (); 

          latGPS = layer.getLatLng().lat;
          lngGPS = layer.getLatLng().lng;
 
          $('#latitudeEP').val(latGPS);
          $('#longitudeEP').val(lngGPS);
 
          data = $("#formulaireEP").serialize();
 
          $.ajax(
            url: 'assets/php/create/create_EP.php',
            type: $("#formulaireEP").attr('method'),
            data: data,
            success: function() 
              def.resolve();
              dialog_create_EP.dialog("close");
              $("#formulaireEP")[0].reset();
            
          )
          promises.push(def)
        )
      return $.when.apply(undefined, promises).promise();
      
 
      defer.resolve(getAjaxDeffered());
 
      getAjaxDeffered().then(function(data) 
        $.ajax(
          url: owsrootUrlAssainissement + L.Util.getParamString(parametersEP),
          dataType: 'jsonp',
          jsonpCallback: 'callEP'
        ).done(EPvannes1);
      );
      return false;
    ,
    Cancel: function() 
      dialog_create_EP.dialog("close");
    ,
  
);
dialog_create_EP.dialog("open");

【讨论】:

【参考方案2】:

看起来您的 layer.eachLayer 函数没有返回 Promise/Deferred。沿着 jQuery 文档:

如果单个参数被传递给 jQuery.when() 并且它不是 Deferred 或 Promise,它将被视为已解决的 Deferred 和 任何附加的 doneCallbacks 都会立即执行。

【讨论】:

以上是关于当另一个完成时执行一个 Ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章

Jquery监听AJAX请求

并行执行多个 AJAX 请求,并在所有请求完成后运行一个函数

jQuery Ajax 操作函数

jQuery Ajax 操作函数

暂停函数执行流程,直到 ajax 请求完成

关于ajax请求等待完成