2015-11-09 106 views
0

我很努力與JavaScript異步模式,以達到這個目標:Javascript類屬性在構造函數中加載異步?

我有一個類(我使用CoffeeScript)與一些屬性在構造函數中從一些異步調用初始化。然後我有一些方法需要這些屬性才能工作。這裏是什麼,我試圖做一個簡單的例子:

# Class definition 
class window.MyClass 
    constructor: -> 
    @attr = ... # loaded with an ajax call or whatever 

    myMethod: -> 
    console.log @attr 

# User code 
c = new MyClass() 
c.myMethod() # should console.log the value loaded asynchronously 

那麼問題將是,當myMethod()被調用時,異步調用尚未完成。

我知道一些解決方案,但它們暗示將方法調用移入回調(或帶有promise的then函數)中。我想避免這個能夠從點擊處理程序或其他完全不相關的東西中調用此方法。

另請注意,我無法在我的方法內移動異步調用,因爲我可能會使用該屬性的幾種方法,並且我不想在每次調用時加載attr,但只在構造函數中加載。

有什麼想法?

回答

0

我終於找到了一種方法來做到這一點。不知道它是否非常乾淨,但它工作並符合我的需求。

在異步加載我的attr值後,我發送一個事件MyClassReady。 在我的構造函數中,我添加了第一個偵聽器MyClassReady,它將屬性ready設置爲true。

然後,在myMethod,我將我的代碼包裝在一個函數中。然後我調用這個函數,如果ready是真的,否則我綁定這個函數到MyClassReady事件。

結果看起來是這樣的:

# Class definition 
class window.MyClass 
    constructor: -> 
    # Async load of `attr` 
    self = this 
    loadAttr (val) -> 
     self.attr = val 
     window.dispatchEvent new Event 'MyClassReady' 

    window.addEventListener 'MyClassReady', -> 
     self.ready = true 

    myMethod: -> 
    self = this 
    callback = -> 
     console.log self.attr 

    # If the attrs are already loaded 
    if @ready 
     callback() 
    else 
     window.addEventListener 'MyClassReady', -> 
     callback() 

# User code 
c = new MyClass() 
c.myMethod() # this will wait until attr is loaded 

我認爲這將是很好,這個代碼移到一個庫,但是所有的東西self = this似乎複雜。

編輯:注意,自定義事件不支持IE ...

相關問題