如何以连续顺序执行多个链式$ .post()调用?

时间:2015-08-22 20:39:17

标签: javascript jquery ajax .post

我正在尝试完成

我需要触发1到3个不同的$.post()请求,并且它是1个呼叫,2个连续呼叫还是3个连续呼叫是由一些基本用户选择决定的。每次通话只能在前一次完成后才开始。

我正在处理3个简单的行为案例 - 用户,出现“Checkbox 1”,“Checkbox 2”和“Continue”按钮,“选择

  1. 选择任何内容然后按“继续”按钮,这会对XRR调用'/remote.php',
  2. 用户选择仅选择“复选框1”“复选框2”,然后按“继续”按钮,该按钮调用绑定到复选框1的$.post() Function 1,或{ {1}}绑定到Checkbox 2,然后对'/remote.php'进行XHR调用,
  3. 或者用户同时选中Checkbox 1 + 2然后按继续,调用$.post() Function 2,然后调用$.post() Function 1,然后对'/remote.php'进行XHR调用。
  4. 我需要确保在Checkbox绑定$.post() Function 2功能触发并完成之前,不会触发“继续”按钮$.post()功能。

    问题

    问题是,如果选中Checkbox 1并选中Checkbox 2,然后按下Continue按钮,据我所知,加载顺序应为:

    1. 复选框1绑定$.post()请求已触发并完成,然后
    2. Checkbox 2绑定$.post()请求触发并完成,然后
    3. 继续按钮绑定$.post()点火,并在与“继续”按钮绑定功能关联的功能结束时通过AJAX更改页面。
    4. 所以,结果应该是这样的:

      $.post()

      它经常出现如下:

      XHR finished loading: POST "/cart.php?action=add&product_id=1280".
      XHR finished loading: POST "/cart.php?action=add&product_id=1284". 
      XHR finished loading: POST "/remote.php".
      

      因此,当页面在“last”/“Continue-button功能结束时由于AJAX而发生变化时,Checkbox 1或Checkbox 2操作都没有发生,或两者之一或两者都注册在后端(即添加到购物车中)但不反映在AJAXified DOM中,因为它们应该在最终的AJAX触发并在之前的$ .post()调用完成之前完成。

      我的代码

      HTML

      HTML是基本的:

      XHR finished loading: POST "/cart.php?action=add&product_id=1280".
      XHR finished loading: POST "/remote.php".
      XHR finished loading: POST "/cart.php?action=add&product_id=1284". 
      

      Javascript / jQuery

      这是我最新的 - 第4次或第5次尝试,但仍无效:

      <form method="post" action="#" onsubmit="newChooseShippingProvider(); return false;">
          <label for="delSigCheck" class="del-sig-text"><input id="delSigCheck" type="checkbox" onchange="addDelSigToCart();" title="Add Delivery Signature"></label>
          <label for="addInsCheck" class="ins-add-calc"><input id="addInsCheck" type="checkbox" onchange="addInsToCart();" title="Add Delivery Signature" data-ins-id="1284"></label>
          <input type="submit" value="Continue" class="btn Small">
      </form>
      

      我尝试过什么

      我已经浏览了几个版本的function addDelSigToCart() { $('#delSigCheck').toggleClass('checked'); } function addInsToCart() { $('#addInsCheck').toggleClass('checked'); } function newChooseShippingProvider() { var originalCheckout = ExpressCheckout.ChooseShippingProvider(); if ($('.ShippingProviderList .radio span').hasClass('checked')) { var addInsCheck = $('#addInsCheck').hasClass('checked'); var delSigCheck = $('#delSigCheck').hasClass('checked'); var insId = $('#addInsCheck').attr('data-ins-id'); var addDelSigUrl = '/cart.php?action=add&product_id=1280'; var addInsUrl = '/cart.php?action=add&product_id=' + insId; if (delSigCheck && addInsCheck) { $.post(addDelSigUrl, function() { $.post(addInsUrl, function() { originalCheckout; }); }); } else if (!delSigCheck && !addInsCheck) { originalCheckout; } else if (delSigCheck && !addInsCheck) { $.post(addDelSigUrl, function() { originalCheckout; }); } else if (!delSigCheck && addInsCheck) { $.post(addInsUrl, function() { originalCheckout; }); } } else { originalCheckout; } 来电,但似乎没有任何工作。

      我现在正在使用的内容以及对我进行大量测试似乎最有效的方法是使用$.post()来延迟链接函数,如下所示:

      setTimeout

      上面的这个版本就是我现在正在使用的,因为它看起来提供了最一致的结果,看到脚本通常加载为1,2,3,然后是基于函数1的适当更改的DOM AJAXified 2.但是,我不认为setTimeout工作正常,即使我将其增加到5000或10000,操作“瞬间”执行并且没有发生延迟(至少肯定没有接近5-10秒)。 / p>

      我也尝试将这些函数放在 ... if (delSigCheck && addInsCheck) { $.post(addDelSigUrl); setTimeout(function() { $.post(addInsUrl); setTimeout(function() { ExpressCheckout.ChooseShippingProvider(); }, 1300); }, 1300); } else if ... 的成功回调中:

      $.post()

      最后我也尝试过:

          ...
          if (delSigCheck && addInsCheck) {
              $.post(addDelSigUrl, function() {
                  setTimeout(function() {
                      $.post(addInsUrl, function() {
                          setTimeout(function() {
                              originalCheckout;
                          }, 1300);
                      });
                  }, 1300);
              });
          } else if ...
      

      以及$.when($.post(addDelSigUrl)).then(originalCheckout); .done但它们都不起作用,并且$ .posts()按意外顺序加载,失败。

      问题

      1. 我做错了什么?
      2. 我怎样才能让它完全加载,然后完全加载2次,只有3次加载和加载?
      3. 更新1:

        我刚试过jfriend00's answer

        success:

        但它仍然导致:

                    $.post(addDelSigUrl, { cache: false }).then(function(data1) {
                        //CONSOLE.LOGing HERE
                        console.log(data1);
                        return $.post(addInsUrl, { cache: false });
                    }).then(function(data2) {
                        //CONSOLE.LOGing HERE
                        console.log(data2);
                        return originalCheckout;
                    });
        

        并且两个console.logs在第一个“XHR ...”之后立即触发,然后THEN /remote.php触发(尽管它应该作为originalCheckout的一部分触发),然后第3个XHR触发。

        更新2

        现在我们通过XHR finished loading: POST "/cart.php?action=add&product_id=1280". XHR finished loading: POST "/remote.php". XHR finished loading: POST "/cart.php?action=add&product_id=1284". 以正确的顺序触发XHR并加载,我遇到的问题的第二部分是第3个XHR到.then()通过AJAX用数据更新DOM从后端。部分数据是第1和第2 /remote.php

        我认为第三个AJAX调用是在通过服务器端PHP在后端采取某些操作之前触发并完成毫秒,并且由于超过50%的时间,通过第三个AJAX调用的DOM更新丢失来自第一次和/或第二次调用的数据(最常见的是DOM更改包括Checkbox 1 / AJAX调用1,但不包括2)。

        我该如何解决这个问题?我已经尝试了setTimeout,但它似乎不起作用,即使我将它设置为30000,第3次/第二次完成后第3次AJAX就会激活。

        最新的前端代码:

        $.posts

2 个答案:

答案 0 :(得分:3)

对jQuery ajax操作进行排序的最简单方法是使用内置的promise:

$.post(...).then(function(data1) {
    return $.post(...);
}).then(function(data2) {
    return $.post(...);
}).then(function(data3) {
    // everything done here
});

工作演示,向您展示精确的排序:http://jsfiddle.net/jfriend00/zcfr2xy0/

好的,问题似乎是您正在执行此操作:

var originalCheckout = ExpressCheckout.ChooseShippingProvider();

然后,您认为稍后,您可以这样做:

originalCheckout;

这将以某种方式执行前者。事实并非如此。您的ExpressCheckout.ChooseShippingProvider()函数立即执行,执行该函数的返回结果将分配给originalCheckout

你根本无法做到这一点。如果在函数名后有(),则表示现在执行它。我建议您只使用originalCheckout;替换ExpressCheckout.ChooseShippingProvider();的所有实例。

答案 1 :(得分:1)

如果你&#34;链&#34; AJAX后期操作(意味着你一旦接收到前一次调用的数据就完成了你的过程),那么就不会发生任何奇怪的事情。

从症状出发,我想到更多与缓存相关的问题。在查询中添加一个额外的随机值是一种快速的方法,可以摆脱那些缓存结果并响应而不是应该响应的人。同样使用POST请求而不是GET(如果可能的话)可能有助于解决这个问题,并且更好地传达了这样一种观点,即操作是一个不应该跳过或无序的突变。

请注意,陈旧的响应问题可能分为几个层次:浏览器,代理,Web服务器,cms插件......