小编典典

在一系列异步XHR调用之后添加“回调”的最佳方法

ajax

我偶然发现了一段不是100%安全的Ajax代码,因为它混合了异步/同步类型的代码…所以基本上在下面的代码中我有一个jQuery.each,其中每个元素都获取有关元素的信息并启动Ajax收到每个请求:

$(search).each(function() {
 $.ajax({
  url: 'save.x3?id='+$(this).attr("id")+'value='$(this).data("value");
  success: function(o){
   //Update UI
  },
  error: function(o){
   //Update UI
  }
 });
});

//code to do after saving...

因此,显然,“保存后要执行的代码…”通常在所有请求完成之前执行。在理想情况下,我想让服务器端代码一次处理所有这些代码,并保存成功回调后将//代码移到要执行的代码中,但是假设这不可能,我将代码更改为如下代码:确保所有请求都返回,然后再继续执行,而我仍然不喜欢:

var recs = [];
$(search).each(function() {
 recs[recs.length] = 'save.x3?id='+$(this).attr("id")+'value='$(this).data("value");
});

var counter = 0;
function saveRecords(){
 $.ajax({
  url: recs[counter],
  success: function(o){
   //Update progress
   if (counter<recs.length){
    counter++;
    saveRecords();
   }else{
    doneSavingRecords();
   }
  },
  error: function(o){
   //Update progress
   doneSavingRecords(o.status);
  }
 });
}

function doneSavingRecords(text){
 //code to do after saving...
}

if (recs.length>0){
 saveRecords();  //will recursively callback itself until a failed request or until all records were saved
}else{
 doneSavingRecords();
}

因此,我正在寻找向一系列异步调用中添加一些同步功能的“最佳”方法?

谢谢!!


阅读 378

收藏
2020-07-26

共1个答案

小编典典

更好的答案

function saveRecords(callback, errorCallback){
  $('<div></div>').ajaxStop(function(){
    $(this).remove(); // Keep future AJAX events from effecting this
    callback();
  }).ajaxError(function(e, xhr, options, err){
    errorCallback(e, xhr, options, err);
  });

  $(search).each(function() {
    $.get('save.x3', { id: $(this).attr("id"), value: $(this).data("value") });
  });
}

可以这样使用:

saveRecords(function(){
   // Complete will fire after all requests have completed with a success or error
}, function(e, xhr, options, err){
   // Error will fire for every error
});

原始答案 :如果它们需要按一定顺序排列,或者页面上有其他常规AJAX事件会影响的使用ajaxStop,则这样做会很好,但这会比较慢:

function saveRecords(callback){
  var recs = $(search).map(function(i, obj) {
   return { id: $(obj).attr("id"), value: $(obj).data("value") };
  });

  var save = function(){
   if(!recs.length) return callback();

   $.ajax({
    url: 'save.x3',
    data: recs.shift(), // shift removes/returns the first item in an array
    success: function(o){
     save();
    },
    error: function(o){
     //Update progress
     callback(o.status);
    }
   });
  }

  save();
}

然后您可以这样称呼它:

saveRecords(function(error){
   // This function will run on error or after all 
   // commands have run
});
2020-07-26