jQuery延迟链接问题

时间:2011-08-31 04:06:00

标签: javascript jquery

好吧,我可能错过了一些明显的东西,虽然我试图找到一个类似的例子,但我找不到一个我想做的事情。我需要一系列ajax调用以特定顺序运行。我正在使用以下代码来完成事务:

showStandbyDialog();
    $.when(function(){console.log('Paying Charges due before transaction');})
        .always( this.applyCredit(parseFloat($(this.currentChargesTarget).html())) ) // Pay charges due before transaction
        .always(function(){console.log('Applying renewals');})
        .always( this.applyRenewals() ) // Apply Renewals
        .always(function(){console.log('Paying renewal charges');})
        .always( this.applyCredit(this.renewCart.length * this.renewCost) ) // Pay renewal charges
        .always(function(){console.log('Applying checkouts');})
        .always( this.applyCheckOut() ) // Apply checkouts
        .always(function(){console.log('Paying checkout charges');})
        .always( this.applyCredit(this.cart.length * this.checkOutCost) ) // Pay checkout charges
        .always(function(){console.log('Applying card replacement');})
        .always( this.applyCardReplacement() ) // Apply card replacement
        .always(function(){console.log('Paying leftover charges');})
        .always( this.applyCredit(this.cardCost) ) // Pay leftover charges
        .always(function(){console.log('Finalizing Transaction');})
        .always( function(){ updateCharges(); bfwd.Patron.Transaction.reset(); hideStandbyDialog(); } ); // Reset Transaction and clear standby dialog

现在我尝试了.done,.then,以及几乎.anything()但是this.applyCredit()的handle函数中的console.log()代码总是在console.log之后记录('Finalizing Transaction “)。每个this.function()调用都会返回一个jquery延迟方法,以防你想知道。

2 个答案:

答案 0 :(得分:8)

我在这里完全重新制作了我的jsFiddle:http://jsfiddle.net/JohnMunsch/nxPn3/

大约10次:)

.always()将在第一个.when()中完成的相同Deferred对象(或Promise)返回给所有其他.always()函数。所以他们快速接连了。看起来大致如此。

Step 1: log.
Step 2: kick off ajax call, log, kick off ajax call, log, kick off ajax call, log, etc. etc.

直到我在每个“ajax调用”函数中放置定时器才使它们延迟一段时间,我才真正看到它。然后我一直有这个问题,如何在没有嵌套上一步的.done()函数中的每个下一步的情况下执行此操作?

我对那个问题的解决方案可能不是最优雅的,但它确实有效。我预先创建了一组完整的Deferred对象,并使用它们来防止每个连续的步骤开始,直到上一步被标记为已解决或被拒绝。

以下是摘录:

console.log('Paying Charges due before transaction');
var step1 = applyCredit("parseFloat($(this.currentChargesTarget).html())");
var step2 = new $.Deferred();
var step3 = new $.Deferred();

$.when(step1).done(function(){
    console.log('Applying renewals');
    $.when(applyRenewals()).done(function () {
        step2.resolve();
    });
}).fail(function () { step2.reject() });

$.when(step2).done(function(){
    console.log('Paying renewal charges');
    $.when(applyCredit("some subcalc")).done(function () {
        step3.resolve();
    });
}).fail(function () { step3.reject() });

现在当你运行jsFiddle时,每个函数调用都会在一个完美的行中前进。第二个没有开始,直到第一个完成,第三个不能开始,直到第二个完成...

答案 1 :(得分:4)

好的,我已经找到了如何做你原来问的第一个答案,这是我的第二个答案。不要这样做。

请勿使用客户端对服务器上的八步财务流程进行排序。哎呀,不要用它来对服务器上的两步财务流程进行排序。当服务器出现故障,用户关闭他/她的笔记本电脑或丢失互联网连接时会发生什么?你最终可能完成了步骤1-3或者从一个本应作为一个单元执行的序列中完成了1-5步。

对服务器进行 ONE AJAX调用,并为其执行所有八个步骤提供所需的信息。如果可能,在服务器上使用服务器支持的事务,或使用数据库事务确保所有操作一起成功,或者它们一起失败,如果出现任何故障,所有操作都将回滚到其原始状态。然后,您可以向客户报告所发生事件的结果,包括您需要或想要的每个步骤的详细信息。