2015-10-19 6 views
5

Node.jsでは、コールバックを使用するのがベストプラクティスであるときに、クラスメソッドをどのように連鎖させますか?一緒にチェーン方法あなたが望んでいたような回数にあなたを許さコールバックを持つチェーンクラスメソッド?

class MyClass { 

    function get() { 
    // fetch some data from an API endpoint 
    return this; 
    } 

    function set(property, value) { 
    // Set the property to some value on the object 
    return this; 
    } 

    function save() { 
    // Save the data to database 
    return this; 
    } 
} 

$myObject = new MyClass(); 
$myObject->set('something','taco')->save(); 

この非常に一般的なオブジェクト指向のアプローチ:私のPHPの時代には

は、私は通常、このような何かをするだろう。

Node.jsを使用している場合でも、これと同様のチェーン接続が可能ですか?それともコールバック地獄で終わるのですか?すべての「チェーン」はネストされたコールバックですか?

または、私のスクリプトを約束で包むだけでいいですか?

new Promise(function(resolve, reject){ 
    var myObject = new MyClass(); 
    myObject.set('something','taco'); 
    resolve(myObject); 
}).then(function(myObject){ 
    myObject.save(); 
}); 

あなたはそれをやるべきですか?これをもっと深く私のクラスに統合する方法はありますか?毎回約束する必要はありませんか?私はいくつかの図書館がhttps://github.com/sindresorhus/gotのような "promise-mode"のようなものを持っているのを見たことがありますが、コードを見ても、どうやって彼らがそれをしたのかまだ正確にはわかりません。

+0

は、これはあなたが探しているものでしょうか? https://github.com/kriskowal/qとhttps://www.npmjs.com/package/q –

+0

ノード4.xでPromiseライブラリを使用しないでください。 –

+0

私は、各メソッドで新しいPromisesを返すだけで、 '.then'を使って連鎖させることができます。そうですか? –

答えて

4

同期呼び出しの場合はreturn thisを使用してチェーンします。

Promiseを使用するチェーン、または非同期呼び出しのコールバック。

class MyClass { 
 
    
 
    get() { 
 
    return new Promise((resolve, reject)=> { 
 
     // Make Request and call resolve(result) or reject(err) 
 
    }); 
 
    } 
 
    
 
    set(property, value) { 
 
    this[property] = value; 
 
    return this; 
 
    } 
 
    
 
    save() { 
 
    return new Promise((resolve, reject)=> { 
 
     // Make Request and call resolve(result) or reject(err) 
 
    }); 
 
    } 
 
} 
 

 
var myObject = new MyClass(); 
 

 
myObject 
 
    .set('something', 'taco') 
 
    .save() 
 
    // resolve handler 
 
    .then((saveResult)=> { 
 
    console.log(saveResult); 
 
    return myObject.get(); 
 
    }) 
 
    // resolve handler 
 
    .then((getResult)=> { 
 
    console.log(getResult); 
 
    }) 
 
    // reject handler 
 
    .catch((error)=> { });

+0

興味深いので、それは2の組み合わせです。私はこれを使いこなすでしょう。ありがとう –

+0

例えば、 'myObject.set(...)。save()。set(...)'のように連鎖することはできますか?私は、PHPでできるように、私のクラスの任意のメソッドを別のメソッドに連結する方法を理解しようとしています。しかし、その可能性は確かです。 –

+0

PHPはマルチスレッドでもイベントループでもないので、JavaScriptのような非同期メソッドについては心配する必要はありません。これはPHPの欠点です。待っている間にリソースを無駄にする可能性があるからです。物事を処理するには 'Promises'や' async'のようなライブラリを使わなければなりません。 – TbWill4321

0

あなたは特別なプライベートメンバ変数__lastPromiseを保存することができます。最初はデフォルトで解決されます。しかし、タスクを実行する関数は、それをリターンの約束で更新します。また、関数自体は、の後にのみ、の前にという約束が保存されています。このよう

save() { 
     // only after __lastPromise has resolved 
    var newPromise = __lastPromise.then(function() { 
     // Do stuff here 
    }); 

    // update __lastPromise with the newly returned promise 
    this.__lastPromise = newPromise; 

    // return this for regular chaining 
    return this; 
} 

コンプリートクラス:

class MyClass { 
    constructor(){ 
     this.__lastPromise = Promise.resolve(); 
     this.a = 0; 
    } 
    set(property, value) { 
     var self = this; 
     self.__lastPromise = self.__lastPromise.then(function() { 
      return new Promise(function(resolve, reject) { 
       console.log('self.%s set to: ', property, value); 
       self[property] = value; 
       resolve(); 
      }); 
     }); 
     return self; 
    } 
    save() { 
     var self = this; 
     self.__lastPromise = self.__lastPromise.then(function() { 
      return new Promise(function(resolve, reject) { 
       console.log('Saved'); 
       resolve(); 
      }); 
     }); 
     return self; 
    } 
} 
var myObject = new MyClass(); 
myObject.set('a', '1').save().set('a', '2').save(); 
this.a set to: 1 
Saved 
this.a set to: 2 
Saved 
+0

すべての操作をシーケンスする必要がない限り、このアプローチを使用しないことをお勧めします。 – Bergi

関連する問題