我有一个网页,我在这个页面上有5个复选框。使用while循环我正在浏览所有选中的复选框,并在选中时执行AJAX调用。
问题是复选框的顺序很重要。或者至少第一个AJAX调用必须在其他AJAX调用完成之前执行一些特殊操作。然而,似乎所有AJAX调用都以正确的顺序完成,后面的PHP代码没有以相同的顺序执行,这导致第一个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);
$('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,因此第一个 然后它发送表单2,索引4,然后表单3,索引2,等等。
因此,表格“完成”的顺序与它们的应用方式不同> 4,0,2,1,3代替0,1,2,3,4。订单每次都不同。
使用参数first
我希望tel脚本/addtocart
,它是第一个排队的,所以它应该做一些特别的事情。但不幸的是,第一次并不总是第一次。
顺便说一句:
顺序并不那么重要,唯一重要的是在脚本/addtocart
中我必须知道它是第一个。
答案 0 :(得分:2)
每个ajax函数都会返回一个使用它的promise对象。 promises
将包含所有ajax承诺,$.when
将解析所有ajax调用并触发回调done
;
试试这个
$("#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';
});
});
答案 1 :(得分:1)
如果重构循环以便只是收集数组中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负载,它就会成为瓶颈(特别是在移动设备上)。我常常使用这种技术回退到顺序异步。