2009-06-03 38 views
4

我們的Flex應用程序的初始化代碼正在執行一系列異步調用來檢查用戶憑據,加載外部數據,連接到JMS主題等。根據應用程序的上下文運行時,其中一些調用不會被執行或使用不同的參數執行。處理異步控制結構(Fluent接口?)

由於所有這些調用都是異步發生的,因此控制它們的代碼很難閱讀,理解,維護和測試。對於每次調用,我們都需要一些回調機制,在這種機制中我們決定接下來要執行的調用。

我想知道是否有人嘗試用可執行單元包裝這些調用,並有一個連接和控制它們的Fluent接口(FI)。

從我的頭頂,代碼可能看起來像:

var asyncChain:AsyncChain = execute(LoadSystemSettings) 
.execute(LoadAppContext) 
.if(IsAutologin) 
    .execute(AutoLogin) 
.else() 
    .execute(ShowLoginScreen) 
.etc; 
asyncChain.execute(); 

的AsyncChain將是一個執行樹,與FI建設(我們當然也可以建立一個沒有FI) 。

這可能是在像Flash播放器,Silverlight的,JavaFX的?單線程模型運行環境的一個有趣的想法...

之前,我深入到代碼嘗試的事情了,我希望得到一些反饋。


更新19/03/2010:我們已經創造了春季ActionScript項目,提供了與異步過程控制的實驗任務API。我們很樂意獲得反饋。 http://www.springactionscript.org/docs/reference/html/the_operation_api.html#tasks

回答

0

因爲你的函數必須是異步的,所以你不能讓它們阻塞來等待下一個動作,所以他們所做的只是將一些代碼存儲在稍後將被執行的結構中。

聽起來很熟悉嗎?總之,你正在編譯一種語言並執行一個虛擬機。

沒有什麼不對,但用正確的詞語思考會讓你尋找合適的文獻。例如,而不是與你的內部結構戰鬥,所以.else()部分知道它與哪對配對,只需編寫一個完整的解析器並將其與您的程序一起發送一個字符串即可。

也有很多關於編寫簡單虛擬機的例子

1

當然你可以做到這一點。您可以傳遞動作和繼續功能,並威脅它們進行異步調用和回調。這被稱爲Continuation passing style。這將需要將常規邏輯轉換爲函數調用序列。

直截了當的方法是引入一些monadic框架(like in Haskell)來封裝你的異步調用。但是在將程序邏輯轉換爲CPS時,您仍然需要創建多個函數(回調函數)。參見: CPS in Haskell。但語法很醜。 Scheme中有很好的語法,但這與Scheme計算模型緊密相關:可用於宏處理的宏和庫代碼。

通過一些語言支持,您可以簡化語法:例如F#中的計算表達式,正好爲async one。在引擎蓋下與Monad概念相近。

高級事件驅動編程的另一個有趣想法是在Reactive Extensions for .NET (Rx)中實現的。這個想法很簡單:事件與列表非常相似。不同的是,你不構造它們(基於推送的集合),而是你從它們中獲得下一個元素(基於拉取的集合)。相應地顛倒接口:而不是IEnumerator中的MoveNext和Current,您將在IObservable中獲得OnNext,OnDone和OnError。然後,結合現有的觀察結果,你可以得到接近你建議的代碼的東西。

0

這很多是關於這種類型的編程非常有趣的討論。它也是我們最常用語言中最薄弱的部分,在同步語言中表達異步邏輯是非常痛苦的。我相信繼續是這裏的答案,因爲我們可以認爲同步和程序同步,但模型異步程序控制流程很容易。同步編程非常瞭解並且重複使用非常容易。異步沒有。但是,直到世界趕上......唉。

你的建議看起來很有趣,但我現在至少做了兩次這樣的事情,從來沒有滿意過。我認爲在運行時你會很難評估你的if塊。我一直有的問題是以一種乾淨的方式從一步到另一步地獲取數據。你打算如何寫一個if語句來針對在步驟運行之後可能不存在的值。

如果我是你,我會考慮看看國家模式。狀態模式在對象中模擬這種類型的行爲,並且可以異步執行轉換。 YOu可能能夠創建一個Fluent界面來創建狀態,就像你上面那樣。

我會非常感興趣的聽到它是如何進行的,因爲我現在正在做AIR應用程序中的確切事情,而且我只是很滿意。

2

我已經做了類似的工作,專門用於應用程序的初始化。不過,由於我們使用Flex開發了大多數Flash應用程序,因此我在考慮MXML用法的情況下編寫了它。

的語法看起來就像聲明數組(我只是做了標記,但你的想法):

<Initialize> 
    <DisplayPreloader /> 
    <LoadConfiguration id="configurationLoader" source="foo.xml" /> 
    <ParseConfiguration source="{configurationLoader.result}" /> 

    <!-- ... ---> 
</Initialize> 

使用的接口,如實現IMXMLObject它工作得很好,只是拍這個一個應用程序和嘿presto,這是你的初始化代碼。當然,這不一定是初始化,它可以應用於任何地方。

顯着的優點:

  • 執行順序是直觀,容易改變(只是移動標籤向上或向下)
  • 步驟列表並不真正關心其他步驟
  • 數據可以步驟之間通過使用結合語法來傳遞,促進扶養注射
  • 正確封裝單任務的步驟可以很容易地被重新使用

顯着的缺點:

1

如果涉及到使用Flex和讓我在異步調用流程中使用nsight我會使用架構框架Mate。正如Api所述:'Mate的基本部分是EventMap標記,它允許您爲應用程序創建的事件定義映射。它基本上是一個IActionList塊的列表,其中每個塊匹配一個事件類型[..]「現在,在每個EventMap中,可以有多個邏輯上相互連接的異步服務器調用,整個事情是基於mxml標記的,所以非常容易閱讀。