2011-08-31 103 views
1

好吧,我可能错过了一些明显的东西,虽然我试图找到一个类似的例子,但我找不到一个和我想要做的很像的事情。我需要一系列的ajax调用以特定的顺序运行。我使用下面的代码来完成交易:jQuery推迟链接问题

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,。那么,只是约.anything(),但在手柄功能的console.log()代码this.applyCredit()总是在console.log('Finalizing Transaction')之后记录日志。如果您想知道,每个this.function()调用都会返回一个jquery延迟方法。

+2

你调用的是异步的函数吗?否则,没有理由使用延期。只需创建一个函数,以直接程序编程的适当顺序调用所有这些其他函数。如果它们是异步的,那么向我们展示它们的代码,以便大家可以评估您是否正确使用了延期API。 – jfriend00

+0

他说这是一系列的ajax调用,所以我只是假设... –

+0

对不起,没有注意到这些意见。我想这不会发布代码。 1秒。 – LordZardeck

回答

8

我彻底重塑我的jsfiddle这里:http://jsfiddle.net/JohnMunsch/nxPn3/

约10倍:)

。总是()的返回相同的延迟对象(或承诺),其已在第一。当完成()到所有其他.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,沿着一个完美的行中的每个函数调用游行。第二个不启动,直到第一个已完成,第三不能开始,直到第二后...

+0

好吧,我检查过它是否返回一个包含所有.then和.done函数以及所有内容的对象。确切地说,它返回这个:jQuery.post() – LordZardeck

+1

非常感谢你。这很有效。我的知识库肯定会保留这一点,因为我的程序中有很多事情需要同步工作。 – LordZardeck

4

OK,已经想通了我的第一个答案,怎么做你原来问,这里是我的第二回答。不要这样做。

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

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

+1

我一次只能做一件事的原因是每次行动都可能失败。并且每个动作都应该在允许下一个动作继续之前检查失败(尚未实现,因为您可以看到)。如果有人失败,它会停止该进程,提醒用户,并保持其余数据完好无损,以便用户不会失去其进度。 – LordZardeck

+0

我也明白,我可以找到一种方法来编写它,以便服务器完全处理它,并且我可能会重新编写它,所以我的项目目前并不担心它而且我更关心如何让这一切首先运作。但你确实有一点,是正确的。服务器应该处理所有的数据和逻辑,客户端只显示该信息。希望我可以将两者都标记为答案。 – LordZardeck