2017-05-23 21 views
0

我想實例化一個服務層類「foo」,它將負責調度API調用到代表我的表示層的任何地方。但是,「foo」所需的必要資源只能通過對不同端點進行AJAX調用才能實現。創建一個具有它的字段的對象取決於AJAX調用

例如,考慮foo是否需要獲取當前登錄用戶的accountId才能完成請求。但是,只有通過網絡調用端點「bar」才能使用accountId。

因此,我需要鏈接foo的呼叫與酒吧。

bar.getAccountId().then((accountId) => { foo.getInformation(accountId) }); 

但這意味着每當foo需要提出請求時,它將首先被bar的網絡調用阻止。如果我們知道一個事實,即在用戶在網站上使用的時間內,accountId不會改變,那麼它將是我們將accountId存儲到foo字段的理想選擇。

即Foo的構造函數中,我希望能夠做這樣的事情:

construtor() { bar.getAccountId().then((accountId) => {this._accountId = accountId }); 

現在,每當FOO需要撥打電話,我可以簡單地使用,而不是把網絡電話吧_accountId,讓我的呼籲只是foo的:

foo.getInformation() //we no longer need to supply an accountId, since it's cached inside foo. 

但是,由於我們的構造現正AJAX調用,有沒有辦法讓我們知道呼叫是否已完成與否。如果我們嘗試這樣做:

var foo = new Foo; foo.getInformation() 

我們不能確定foo的構造函數是否已經收到來自bar的響應。我提出的一個解決方法是簡單地將該承諾緩存在構造函數中。例如: -

//CLASS FOO 
constructor() { 
    this._promise = bar.getAccountId().then((accountId) => { 
    this._accountId = accountId; 
    }) 
} 

getInformation() { 
    if (this._promise.hasResolved()) { 
    return makeNetworkCall(this._accountId) 
    } else { 
    this._promise.then(() => { 
     return makeNetworkCall(this._accountId); 
    }) 
    } 
} 

我想知道是否有一個現有的設計模式來解決這個問題,因爲我敢肯定,這是不夠的情況普遍。

回答

1

我會將請求放在getInformation()調用中,並讓它緩存調用的結果。然後在將來的調用中,您可以檢查緩存的值,並使用緩存的值向調用方返回已解析的承諾。

喜歡的東西:

//CLASS FOO 
constructor() { 
    this._accountId = null; 
} 

getInformation() { 
    if (this._accountId !== null) { 
     // If value cached, return resolved promise with value. 
     return Promise.resolve(this._accountId); 
    } 

    // Otherwise, retrieve the value and cache it. 
    return bar.getAccountId().then((accountId) => { 
     this._accountId = accountId; 
     return accountId; 
    }); 
} 
+0

這符合我的需求非常好,謝謝 – user3605508

0

一般來說,構造並不做任何異步工作的好地方。它應該初始化對象併爲其他功能留下重任。

你可以簡單地創建,加載所有必要的數據,並返回一個承諾,你可以繼續使用爲目的的init()方法:

var foo = new Foo; foo.init().then(()=> { 
    // doMoreAsyncStuff(); 
}); 
+0

這效果很好,在類似的帖子中被高度提倡。不幸的是,我綁定的某些框架將不會調用Foo的init函數,並且手動觸發它最終會導致與在構造函數中調用它相同的問題。 (我沒有控制init是否在框架調用foo.doSomethingAsync()之前完成) – user3605508

相關問題