2015-10-19 68 views
5

在Node.js中,當最佳實踐使用回調函數時,如何將類方法鏈接在一起?帶回調的鏈類方法?

在我的PHP日子裏,我通常會做這樣的事情:

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(); 

這允許您鏈方法一起使用多次,你想很普通的面向對象方法。

在使用Node.js時,你還能以某種方式進行類似於此的鏈接嗎?或者你只是在回調地獄?每一個「鏈」是一個嵌套的回調?

或者我只需要將我的腳本包裝在Promises中?

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這樣的「承諾模式」,但是在查看代碼之後,我仍然不確定他們是如何做到的。

+0

這是你在找什麼? https://github.com/kriskowal/q和https://www.npmjs.com/package/q –

+0

那麼我不會在Node 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'-like庫來處理事情。 – 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