2011-01-14 68 views
1

我在辯論一個非常典型的問題的兩種方法:瞭解事件何時發生或立即響應,如果它已經發生。迴應可能已發生的事件

在方法一中,MyLoader1的用戶添加一個事件偵聽器,如果加載器已經完成,它將立即觸發。

class MyLoader1 extends EventDispatcher 
{ 
    private var _isComplete:Boolean = false; 

    public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void 
    { 
     super.addEventListener(type, listener, useCapture, priority, useWeakReference); 

     // if the operation is already complete, immediately notify listeners 
     if(_isComplete) 
     { 
      dispatchEvent(new Event(Event.COMPLETE)); 
     } 
    } 
} 

class Application1() 
{ 
    function main():void 
    { 
     new MyLoader1().addEventListener(Event.COMPLETE, onComplete); 
    } 
} 

在方法2,MyLoader2的用戶必須首先決定是否繼續或增加一個監聽器,這就是後來發射前檢查MyLoader2的完成狀態。

class MyLoader2 extends EventDispatcher 
{ 
    private var _isComplete:Boolean = false; 

    public function get isComplete():void 
    { 
     return _isComplete; 
    } 
} 

class Application2() 
{ 
    function main():void 
    { 
     var loader:MyLoader2 = new MyLoader2(); 

     if(loader.isComplete) 
     { 
      // passing null just to simplify the example 
      onComplete(null); 
     } 
     else 
     { 
      loader.addEventListener(Event.COMPLETE, onComplete); 
     } 
    } 
} 

每種方法都有哪些優點/缺點?在這種情況下,我可以/應該使用哪種設計模式?

我傾向於第一個,因爲它需要較少的Loader類知識和較少的代碼來利用它。當有多個偵聽器時,它可能會產生不希望的副作用,因爲每次添加偵聽器時,事件都會觸發一次。

第二種方法是可以理解的,並且更易於調試,但需要更多的前期工作,似乎打破了Loader的封裝。

回答

2

的想法,我喜歡你的第一種方法更好。不過,我認爲爲每個聽衆分派一個事件並不是一個問題,事實上,這就是事件機制背後的想法。如果您有N個對象在發生FooEvent時需要通知,則必須在發生此事件時爲每個對象分派事件。

話雖如此,我不會在addEventListener方法派遣事件;我認爲這是不必要的副作用,真的。這違背了任何人的合理期望。添加偵聽器不應該導致事件觸發。它應該只註冊一個監聽器。您應該檢查數據是否已經加載到您的加載函數中,並在數據可用時分派事件(因爲那時您的加載操作已完成;而不是在您添加偵聽器時)。

另一件事:我明白,如果可能,我想立即派遣。但是,這有一個問題,可能是嚴重的,會導致煩人,而不是那麼明顯的錯誤。如果你立即派遣你基本上有2個接口:一個異步和一個同步。可以在調用代碼中正確處理,但它需要更多的工作,並且很容易出錯,尤其是如果你在某處連接了事件(我曾犯過這種異步/同步加載器的錯誤,並且我學到了這一點艱辛的道路)。

它更簡單,並且在數據立即可用時延遲事件的分派幾乎沒有區別。只是一個小小的延遲,使處理事件的代碼異步運行(setTimeout(dispatchComplete,10)將執行它),在一個不同的堆棧框架中調用加載程序的代碼。你會爲自己節省一些麻煩,使你的調用代碼更簡單,我認爲這就是你所追求的。

0

雖然稍微偏離主題,但我建議你試試信號。這取決於你正在使用什麼類型的事件(即鼠標事件仍然需要as3事件,因此對於某些情況它可能是一些額外的工作),但是我發現信號更易於實現,並且對於自定義事件,這是我的首選。

使用信號我通常設置一個靜態var作爲主控制器。我發現這比事件監聽器和調度器的互連鏈更好。你可以讓所有的命令驅動你的應用程序/遊戲/網站通過這個漏斗。

我提出這個問題的原因是,如果你走這條路,你基本上有一個聽衆,你有事件之前。因此,如果在事件發生後創建了對象,則可以調查事件是否發生了響應,並且addOnce()函數適用於裝載程序和預計僅發生一次的其他事件。因此,雖然這並不能回答你的問題,我希望它增加了混亂:)

有一個鏈接在這裏給你它是如何工作 http://johnlindquist.com/2010/01/21/as3-signals-tutorial/