2011-08-31 71 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