jQuery Ajax 等待每个函数
jQuery Ajax Wait Each Function
$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 = ('<img src="'+res+'">') ;
$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 请求 1 到 1 或等到完成,我该如何解决这个问题?
您可以使用这样的递归函数一个接一个地执行所有调用:
$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 = ('<img src="'+res+'">') ;
$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 = ('<img src="' + res + '">');
$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));
}
});
}
这里有一种没有递归并使用简单循环的方法:
$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.
});
请注意,我可以 "clever this up" 使用 .reduce
将行数从 6 缩短到 4,但老实说,我宁愿保持循环结构让 OP 感到舒服。这是有效的,因为承诺链接 - 基本上当你 return 来自 then
的动作时,它会在执行下一个 then
之前等待它,你将它链接到。
让我们举个例子:
function log(msg){ // simple function to log stuff
document.body.innerHTML += msg + "<br />";
}
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);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
请注意,执行 $xy('#result'+div)
可能不是一个好主意,因为您正在查询视图层以查找放置在那里的内容 - 考虑将相关的 div 保留为数组并保留引用:)
$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 = ('<img src="'+res+'">') ;
$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 请求 1 到 1 或等到完成,我该如何解决这个问题?
您可以使用这样的递归函数一个接一个地执行所有调用:
$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 = ('<img src="'+res+'">') ;
$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 = ('<img src="' + res + '">');
$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));
}
});
}
这里有一种没有递归并使用简单循环的方法:
$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.
});
请注意,我可以 "clever this up" 使用 .reduce
将行数从 6 缩短到 4,但老实说,我宁愿保持循环结构让 OP 感到舒服。这是有效的,因为承诺链接 - 基本上当你 return 来自 then
的动作时,它会在执行下一个 then
之前等待它,你将它链接到。
让我们举个例子:
function log(msg){ // simple function to log stuff
document.body.innerHTML += msg + "<br />";
}
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);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
请注意,执行 $xy('#result'+div)
可能不是一个好主意,因为您正在查询视图层以查找放置在那里的内容 - 考虑将相关的 div 保留为数组并保留引用:)