jQuery Ajax等待每个函数

$xy('#simpan').click(function() { $xy('input[id="cekbok[]"]:checked').each(function() { var data = (this.value); var div = (this.value); var str = window.location.href; var res = str.replace("wp-admin/options-general.php?page=katalogu-options", "/wp-content/plugins/katalog/includes/img/loading.gif"); var loading = ('') ; $xy.ajax({ type : 'POST', url : '../wp-content/plugins/katalogunique/proses2.php', data: { id : (this.value) }, success:function (data) { $xy('#result'+div).empty(); $xy('#result'+div).append(data); $xy('#tz'+div).remove(); } }); }); }); 

我的函数在循环中向proses2.php发送复选框值,但是当我运行此脚本时,它将立即运行所有ajax POST调用。 我想逐个运行ajax请求或等到完成,我该如何解决这个问题?

这是一种没有递归并使用简单循环的方法:

 $xy('#simpan').click(function() { var url = '../wp-content/plugins/katalogunique/proses2.php'; var d = $.Deferred().resolve(); // empty promise $xy('input[id="cekbok[]"]:checked').each(function() { var div = this.value; d = d.then(function(data){ $xy('#result'+div).empty().append(data); $xy('#tz'+div).remove(); return $xy.post(url, {id: div}); // this will make the next request wait }); }); // can d.then here for knowing when all of the requests are done. }); 

注意我可以通过.reduce “聪明起来” .reduce行数从6缩短到4,但老实说,我宁愿保持循环结构OP很舒服。 这是因为承诺链接 – 基本上当你从a返回一个动作时它将在执行下一个之前等待它then你将它链接到。

让我们举例说明:

 function log(msg){ // simple function to log stuff document.body.innerHTML += msg + "
"; } var delay = function(ms){ // this is an async request, simulating your AJAX var d = $.Deferred(); setTimeout(d.resolve, ms); // resolving a deferred makes its then handlers execute return d; }; // $.Deferred.resolve() starts a new chain so handlers execute var p = $.Deferred().resolve().then(function(){ log("1"); return delay(1000); // like in your code, we're waiting for it when we chain }).then(function(){ // in the above code, this is the d = d.then part, log("2"); // this only runs when the above delay completes return delay(1000); }); // and more like in the above example, we can chain it with a loop: [3,4,5,6,7,8,9,10].forEach(function(i){ p = p.then(function(){ log(i); return delay(1000); }); });
  

您可以使用这样的递归函数一个接一个地执行所有调用:

 $xy('#simpan').click(function() { var str = window.location.href; var i=0; things = $xy('input[id="cekbok[]"]:checked'); (function doOneTask(){ if (i++>=things.length) return; var thing = things[i]; var data = thing.value; var div = thing.value; var res = str.replace("wp-admin/options-general.php?page=katalogu-options", "/wp-content/plugins/katalog/includes/img/loading.gif"); var loading = ('') ; $xy.ajax({ type : 'POST', url : '../wp-content/plugins/katalogunique/proses2.php', data: { id : thing.value }, success:function (data) { $xy('#result'+div).empty(); $xy('#result'+div).append(data); $xy('#tz'+div).remove(); } }).always(doOneTask); })(); }); 

注意 :如果您想在第一次失败时停止,而不是像我一样进行下一次调用,请always替换为done

一种方法是使用递归函数,每次返回列表(减去第一个条目)。

例如,调用代码简化为:

 $xy('#simpan').click(function() { LoadAjax($xy('input[id="cekbok[]"]:checked')); }); 

并且LoadAjax是递归的,如下所示:

 function LoadAjax(elements) { // Exit when done if (!elements.length) return; var $this = elements.first(); var data = ($this.value); var div = ($this.value); var str = window.location.href; var res = str.replace("wp-admin/options-general.php?page=katalogu-options", "/wp-content/plugins/katalog/includes/img/loading.gif"); var loading = (''); $xy.ajax({ type: 'POST', url: '../wp-content/plugins/katalogunique/proses2.php', data: { id: ($this.value) }, success: function (data) { $xy('#result' + div).empty(); $xy('#result' + div).append(data); $xy('#tz' + div).remove(); // Go recursive with the rest of the list LoadAjax(elements.slice(1)); } }); }