簡體   English   中英

JavaScript中的可鏈接,基於Promise的類接口

[英]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。

讓我們看看這兩種方法:

流體界面

這意味着您的所有方法都返回實例,它們也必須排隊,因此事情不會“立刻”發生。 我們可以通過修改每次調用的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM