![](/img/trans.png)
[英]What should JavaScript class constructor return when it fails in promise-based way?
[英]Chainable, Promise-based Class Interfaces in JavaScript
我在JavaScript中編寫一個具有以下屬性的構造函數:
function WhizBang() {
var promise;
this.publicMethod_One = function publicMethod_One() { ... };
this.publicMethod_Two = function publicMethod_Two() { ... };
promise = asyncInit();
}
因此,調用new WhizBang()
的asyncInit()
將啟動asyncInit()
過程。 從上面的代碼中可以明顯看出,在對asyncInit()
調用關閉之前,接口中的所有公共方法都不應該運行。
因此, publicMethod_One()
的定義可能如下所示:
function publicMethod_One() {
promise
.then( doStuff )
.catch( reportInitFailure )
;
function doStuff() { ... }
function reportInitFailure() { ... }
}
doStuff()
中發生的一些事情是異步的; 其中一些不是。
所以,如果我班級的最終用戶做了這樣的事情:
function main() {
var whizBang = new WhizBang();
whizBang
.publicMethod_One()
.publicMethod_Two()
;
}
在asyncInit()
關閉之前, asyncInit()
調用publicMethod_One()
。 並且在asyncInit()
和publicMethod_One()
都關閉之前, asyncInit()
調用publicMethod_Two()
。
如何定義我的類方法以使它們可鏈接?
我認為我需要做的是定義一個類,其公共方法都等同於在promise上調用then()
,然后是類特定的實現內容。
互聯網,停了!
(在你的答案中使用Bluebird Promise Library的獎勵積分。)
你現在擁有的實際上非常好。 因為你在一個promise中緩存了asyncInit
的結果,並且每個人都在等待相同的承諾 - 這些函數中的任何代碼都不可能在promise完成之前運行。
function publicMethod_One() {
promise // the fact you're starting with `promise.` means it'll wait
.then( doStuff )
.catch( reportInitFailure );
}
因此,不是強迫人們等待使用publicMethod_One
他們已經可以立即調用它,而像doStuff
這樣的方法只會執行已經解決的promise。
好吧,就像你注意到你的代碼有一個主要問題一樣,給定的方法無法知道何時運行或方法對方法進行排序 - 你可以通過兩種方式解決這個問題:
this
接口並對promise進行排隊。 讓我們看看這兩種方法:
這意味着您的所有方法都返回實例,它們也必須排隊,因此事情不會“立刻”發生。 我們可以通過修改每次調用的promise
來實現這一點:
function publicMethod_One() {
promise = promise // note we're changing it
.then( doStuff )
.catch( reportInitFailure );
return this; // and returning `this`
}
您可能還希望公開一個返回當前promise的.ready
方法,以便可以從外部等待操作序列:
function ready(){
return this.promise;
}
這可以實現以下目標:
var ready = new WhizBang().publicMethod_One().publicMethod_One().ready();
ready.then(function(){
// whizbang finished all operations
}); // can also add error handler
在我看來,這是更簡單的方法,所有方法都返回它們創建的承諾,以便它們可以單獨等待:
function publicMethod_One() {
return promise // note we're returning and not changing it
.then( doStuff )
.catch( reportInitFailure );
}
這很好,因為異步操作暴露在外面。
鏈接是可能的,因為你使用.bind
bluebird:
var whiz = new WhizBang();
var res = Promise.bind(whiz).then(whiz.publicMethod_one)
.then(whiz.publicMethod_one);
res.then(function(){
// all actions completed, can also use return values easier.
});
但優點是從外部更容易推理 - 因此我更喜歡這種方法。 就個人而言,我總是喜歡return
有意義的數據,而不是改變內部狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.