繁体   English   中英

在每个循环中执行ajax调用

[英]Do ajax calls in an each loop

我有一个网页,我在这个页面上有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我想电话脚本/addtocart ,它是在第一线之一,所以它应该做一些特别的东西。 但不幸的是,第一个并不总是第一个。

BTW:

顺序并不那么重要,唯一重要的是在脚本/addtocart我必须知道它是第一个。

每个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';
    });

});

如果重构循环以便只是收集数组中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负载,它就会成为瓶颈(特别是在移动设备上)。 我经常使用这种技术回退到顺序异步。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM