微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我要完成的工作

我需要触发1到3个不同的$.post()请求,它是1个调用,2个连续调用还是3个连续调用是由一些基本的用户选择决定的.每个呼叫只能在前一个呼叫完全结束之后开始.

我正在处理3个简单的行为案例-向用户显示“复选框1”,“复选框2”和“继续”按钮,“

>不选择任何内容,然后按“继续”按钮,这将对“ /remote.PHP”进行XHR调用,
>用户选择仅选择“复选框1”或“复选框2”,然后按“继续”按钮,这将调用绑定到复选框1的$.post()函数1或调用该复选框的$.post()函数2绑定到复选框2,然后对“ /remote.PHP”进行XHR调用,
>或用户同时选中两个CheckBox 1 2,然后按Continue,这将调用$.post()函数1,然后调用$.post()函数2,然后对’/remote.PHP’进行XHR调用.

我需要确保在复选框绑定的$.post()函数启动并完成之前,不会触发Continue-button $.post()函数.

问题

问题在于,如果按照我的理解,如果选择了复选框1并选择了复选框2,然后按了“继续”按钮,则加载顺序应为:

>复选框1绑定的$.post()请求被触发并完成,然后
>复选框2绑定的$.post()请求被触发并完成,然后
>继续按钮绑定$.post()触发,并且在绑定到“继续”按钮绑定函数函数末尾通过AJAX更改页面.

因此,结果应如下所示:

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".
@H_502_28@

相反,它通常是这样出现的:

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". 
@H_502_28@

因此,当页面由于“最后一个” /“继续按钮”功能结尾处的AJAX而改变时,既没有发生CheckBox 1或CheckBox 2操作,也没有发生两者之一,或者两者都在后端注册(即添加到购物车中),但不会像最终AJAX在先前的$.post()调用完成之前触发并完成时那样反映在AJAXified DOM中.

我的密码

HTML

HTML是基本的:

<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>
@H_502_28@

Javascript / jQuery

这是我最近尝试的第-4或第5-尝试,仍然无法使用:

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;
    }
@H_502_28@

我尝试过的

我已经经历了多个链接$.post()调用的版本,但是似乎没有任何一致的方法.

我现在使用的是什么,对于广泛的测试来说,最适合我的方法是使用setTimeout延迟一段时间来链接函数,如下所示:

    ...
    if (delSigCheck && addInsCheck) {
        $.post(addDelSigUrl);
        setTimeout(function() {
            $.post(addInsUrl);
            setTimeout(function() {
                ExpressCheckout.ChooseShippingProvider();
            }, 1300);
        }, 1300);
    } else if ...
@H_502_28@

上面的版本是我现在使用的版本,因为它似乎提供了最一致的结果,看到脚本的加载通常为1,2,3,然后是基于功能1和2进行了适当更改的DOM AJAXified.但是,我不认为setTimeout可以正常工作,即使我将其增加到5000或10000时,动作是“瞬时”执行的,并且没有延迟发生(至少肯定没有接近5-10秒的时间).

我还尝试将函数放入$.post()的成功回调中:

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

最后,我还尝试了:

$.when($.post(addDelSigUrl)).then(originalCheckout);
@H_502_28@

以及.done和成功:但它们均无效,并且$.posts()的加载以意外的顺序失败.

问题

>我做错了什么?
>如何使它完全装载1次,然后完全装载2次,然后只有3次点火和装载?

更新1:

我刚刚尝试了jfriend00’s answer

            $.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;
            });
@H_502_28@

但这仍然导致:

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". 
@H_502_28@

并且两个console.logs在第一个“ XHR …”之后立即触发,然后/remote.PHP触发(尽管它应作为OriginalCheckout的一部分最后触发),然后第三个XHR触发.

更新2

现在,我们已经通过.then()以正确的顺序触发并加载了XHR,问题的第二部分是我的第三个XHR /remote.PHP使用后端的数据通过AJAX更新了DOM.该数据的一部分是第一个和第二个$.posts.

我认为在通过服务器端PHP对后端执行某些操作之前,第3个AJAX调用正在触发并完成毫秒,因此,超过50%的时间,通过第3个AJAX调用进行DOM更新会丢失来自第一个和/或第二个调用(最常见的DOM更改包括CheckBox 1 / AJAX调用1,但不包括2).

我怎样才能解决这个问题?我已经尝试过setTimeout,但是即使将其设置为30000,它似乎也无法正常工作,一旦第1/2次完成,第3 AJAX就会启动.

最新的前端代码

function newChooseShippingProvider() {
    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).then(function(data1) {
                return $.post(addInsUrl);
            }).then(function(data2) {
                return ExpressCheckout.ChooseShippingProvider();
            });
        } else if (!delSigCheck && !addInsCheck) {
            ExpressCheckout.ChooseShippingProvider();
        } else if (delSigCheck && !addInsCheck) {
            $.post(addDelSigUrl).then(function(data1) {
                return ExpressCheckout.ChooseShippingProvider();
            });
        } else if (!delSigCheck && addInsCheck) {
            $.post(addInsUrl).then(function(data1) {
                return ExpressCheckout.ChooseShippingProvider();
            });
        }
    } else {
        ExpressCheckout.ChooseShippingProvider();
    }
}
@H_502_28@

解决方法:

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

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

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

好的,看来问题在于您正在执行此操作:

var originalCheckout = ExpressCheckout.ChooseShippingProvider();
@H_502_28@

然后,您认为以后的某个时候,您可以这样做:

originalCheckout;
@H_502_28@

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

您根本无法那样做.当函数名称后有()时,表示立即执行.我建议您只替换originalCheckout的所有实例;与ExpressCheckout.ChooseShippingProvider();.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐