web-dev-qa-db-ja.com

オブジェクトをPromise.then()引数にバインドする正しい方法

オブジェクトの関数を単にBluebird thenに渡すことができないという難しい方法を見つけました。私は、Bluebirdのthenがいくつかの魔法を実行し、渡された関数を匿名関数にラップしていると想定しています。そこで、.bind関数に、それは働いた。これはbluebirdでこれを行う正しい方法ですか?それとももっと良い方法がありますか?

var Promise = require("bluebird")

var Chair = function(){
  this.color = "red"
  return this
}


Chair.prototype.build = function(wood){
  return this.color + " " + wood
}

var chair = new Chair()

//var x = chair.build("cherry")

Promise.resolve("cherry")
  .then(chair.build.bind(chair)) // color is undefined without bind
  .then(console.log)

私はこれが非同期ではないことを知っているので、同期の例で裸にしてください、私の使用法は非同期です。

23
ThomasReggi

そこで、.bind関数に、それは働いた。これはbluebirdでこれを行う正しい方法ですか?

はい、それはコンテキストを保持する1つの方法です。また、匿名関数を渡すこともできます(すでに知っているかもしれません)。

Promise.resolve("cherry")
    .then(function (value) {
        return chair.build(value);
    })
    .then(console.log);

それとももっと良い方法がありますか?

実際にbluebirdの Promise.bind メソッド、このような

Promise.resolve("cherry")
  .bind(chair)
  .then(chair.build)
  .then(console.log)

現在、Promiseハンドラー(フルフィルハンドラーまたは拒否ハンドラー)が呼び出されると、関数内でthischairオブジェクトのみを参照します。


注1:この特定のケースでは、console.logthischairオブジェクトとして取得しますが、Node.jsではconsole.log関数は、プロトタイプbuだけでなく、consoleオブジェクトにバインドされたオブジェクト自体でも定義されます。対応するコードは here です。

注2:異なるハンドラが異なるコンテキストを必要とする場合は、無名関数をより適切に作成します。その場合、Promise.bindはあまり役に立ちません。ただし、使用する場合は、ハンドラーごとに異なるコンテキストを使用する必要があり、コードは次のようになります

var chair1 = new Chair("red")
var chair2 = new Chair("green")

Promise.resolve("cherry")
    .bind(chair1)            // Changing the binding to `chair1`
    .then(chair1.build)
    .tap(console.log)
    .bind(chair2)            // Changing the binding to `chair2`
    .then(chair2.build)
    .tap(console.log);
24
thefourtheye