Javascript 在each循环中执行ajax调用
我有一个网页,我在这个网页上有5个复选框。使用whileloop,我正在运行所有选中的复选框,并在选中时执行AJAX调用 问题是复选框的顺序很重要。或者至少第一个AJAX调用必须先执行一些特殊的操作,然后才能执行另一个AJAX调用。然而,似乎所有的AJAX调用都是按正确的顺序执行的,后面的PHP代码不是按相同的顺序执行的,这导致第一个AJAX调用作为第三个调用执行 我怎样才能做到这一点?下面是我的代码Javascript 在each循环中执行ajax调用,javascript,jquery,ajax,Javascript,Jquery,Ajax,我有一个网页,我在这个网页上有5个复选框。使用whileloop,我正在运行所有选中的复选框,并在选中时执行AJAX调用 问题是复选框的顺序很重要。或者至少第一个AJAX调用必须先执行一些特殊的操作,然后才能执行另一个AJAX调用。然而,似乎所有的AJAX调用都是按正确的顺序执行的,后面的PHP代码不是按相同的顺序执行的,这导致第一个AJAX调用作为第三个调用执行 我怎样才能做到这一点?下面是我的代码 $("#submitforms").click(function(){ var btn
$("#submitforms").click(function(){
var btn = $(this);
var first = "true";
var formsSend = 0;
var formsToSend = $(":checkbox:checked").length
var ids = "";
console.log("To send: "+formsToSend);
$('span.postable').each(function(index){
console.log(index);
add = $(this).find('[name="cc"]').is(':checked');
if(add){
btn.css("background-image", "url(/images/wait.gif)");
btn.html("You will be redirected in a second!");
sku = $(this).find('.sku').val();
price = $(this).find('.price').val();
XID = $(this).find('[name="XID"]').val();
$.ajax({
type: "POST",
url: "/addtocart",
data: {sku:sku, qty:"1", price:price, XID:XID, first:first}
}).done(function(data) {
formsSend++;
console.log("Forms send: "+formsSend + " > "+index);
if(formsSend >= formsToSend){
// redirect to cart here after all forms have been posted
console.log("forward");
window.location.href = '/cart';
}
});
first = "false";
}
});
在控制台中显示以下内容
To send: 5
0
1
2
3
4
Forms send: 1 > 4
Forms send: 2 > 0
Forms send: 3 > 2
Forms send: 4 > 1
Forms send: 5 > 3
forward
如您所见,它发送索引为0的表单1,因此
然后它发送带有索引4的表单2,然后发送带有索引2的表单3,以此类推
因此,表单“完成”的顺序与它们应该是>4,0,2,1,3而不是0,1,2,3,4的顺序不同。每次的顺序都不一样
使用参数first
我想告诉脚本/addtocart
它是行中的第一个,所以它应该做一些特殊的事情。但不幸的是,第一次并不总是第一次
顺便说一句:
顺序并不那么重要,唯一重要的是在脚本
/addtocart
中,我必须知道它是第一个。每个ajax函数都将返回一个promise对象,利用它<代码>承诺将包含所有ajax承诺和$。当解决所有ajax调用并启动回调完成
试试这个
$("#submitforms").click(function(){
var btn = $(this);
var first = "true";
var formsSend = 0;
var formsToSend = $(":checkbox:checked").length
var ids = "";
var promises = new Array(); // creating the array for promise.
console.log("To send: "+formsToSend);
$('span.postable').each(function(index){
console.log(index);
add = $(this).find('[name="cc"]').is(':checked');
if(add){
btn.css("background-image", "url(/images/wait.gif)");
btn.html("You will be redirected in a second!");
sku = $(this).find('.sku').val();
price = $(this).find('.price').val();
XID = $(this).find('[name="XID"]').val();
var promise = $.ajax({
type: "POST",
url: "/addtocart",
data: {sku:sku, qty:"1", price:price, XID:XID, first:first}
})
promises.push(promise);// pushing the promise to the array
}
});
$.when.apply($, promises).done(function(){
window.location.href = '/cart';
});
});
如果重新构造循环,使其只需在数组中收集Ajax调用所需的数据,则可以使用递归函数按顺序处理Ajax调用。这样做的好处是它是异步进行的,因此不会阻止任何其他处理 这是对这个概念和你的代码的快速破解
$("#submitforms").click(function () {
var btn = $(this);
var first = "true";
var formsSend = 0;
var formsToSend = $(":checkbox:checked").length
var ids = "";
console.log("To send: " + formsToSend);
var queue = [];
$('span.postable').each(function (index) {
console.log(index);
add = $(this).find('[name="cc"]').is(':checked');
if (add) {
btn.css("background-image", "url(/images/wait.gif)");
btn.html("You will be redirected in a second!");
sku = $(this).find('.sku').val();
price = $(this).find('.price').val();
XID = $(this).find('[name="XID"]').val();
queue.push({
sku: sku,
qty: "1",
price: price,
XID: XID,
first: first
});
}
});
// Now process the queue of data and do processing once all request are completed
ProcessQueue(queue, function () {
formsSend++;
console.log("Forms send: " + formsSend + " > " + index);
if (formsSend >= formsToSend) {
// redirect to cart here after all forms have been posted
console.log("forward");
window.location.href = '/cart';
});
});
});
// Recusively process the Ajax calls (actually this is just chained Async)
function ProcessQueue(queue, callback) {
if (queue.length) {
$.ajax({
type: "POST",
url: "/addtocart",
data: queue[0]
}).done(function (data) {
ProcessQueue(queue.slice(1), callback);
});
} else {
callback();
}
}
抱歉没有考虑到你的计数器等,但这应该指向正确的方向(这是一个普遍有用的技巧)
虽然使用promises是一个很好的选择,但如果您尝试运行并行ajax负载,它将成为一个瓶颈(尤其是在移动设备上)。我经常使用这种技术回退到顺序异步。我经常使用递归(伪)异步函数,它获取异步调用信息列表,并在Ajax完成时使用该列表(减去它的头部,通过切片)调用自己。我还可以在
addtocart
脚本中设置php会话,并在cart
页面中取消设置。如果会话未设置,则表示这是第一次调用。然而,我不确定这是不是一条路要走!如果复选框数据相互依赖,为什么不能在一次呼叫中发送?不确定是否允许单独的ajax调用。您已经忘记了将first
设置为false的位。但是,据我所知,$.when将无法保持请求顺序of@Wolff问题中提到“顺序不太重要”,而承诺
确实是个好主意,并行Ajax调用的负载可能是移动设备上的一个瓶颈(它可以简单地在前几次调用之后丢弃请求)。这就是为什么我在另一个答案中提出了递归异步解决方案,以保持对加载的完全控制。@AntoJSubash顺序并不重要,但第一个必须先发送。我相信顺序现在又是随机的。我也理解这样的OP语句+1 Oops,没有看到问题的BTW部分。请注意,我刚刚将pop()更改为[0],因为它正在处理队列的错误端(将其视为后进先出堆栈…哎哟):)我在ProcessQueue(队列,回调)行上出错{
未捕获的语法错误:意外的标记{.将函数
放在它前面解决了这个问题。但是我仍然无法让代码工作。它没有给出任何错误,但我认为进程队列
没有executed@Timo002:是的,我无法执行您的代码,因此会出现输入错误:)您是否在Chrome中调试或其他东西,以便可以设置断点?如果可以的话一个JSFIDLE模型我可以修复其中的任何错误(看到我把它们放在那里)。这个概念听起来像我以前多次使用过它,但它会是一些我错过的愚蠢细节。一份JSFIDLE中的页面输出HTML副本对初学者来说就行了。