2015-10-19 15 views
5

Trong Node.js, làm thế nào để bạn kết nối các phương thức lớp với nhau, khi nào thực hành tốt nhất để sử dụng các cuộc gọi lại?Phương pháp lớp chuỗi với gọi lại?

Trong những ngày PHP của tôi, tôi thường sẽ làm điều gì đó như thế này:

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

này tiếp cận OO rất phổ biến cho phép bạn phương pháp chuỗi lại với nhau nhiều lần như bạn muốn.

Khi làm việc với Node.js, bạn vẫn có thể thực hiện chuỗi tương tự như thế này? Hay bạn chỉ cần kết thúc trong địa ngục gọi lại? Mỗi "chuỗi" đơn lẻ là một cuộc gọi lại lồng nhau?

Hoặc tôi chỉ cần bao bọc tập lệnh của mình trong Lời hứa?

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

Đó có phải là cách bạn phải làm điều đó không? Có cách nào để tích hợp sâu hơn vào lớp học của tôi vì vậy tôi không phải quấn nó vào lời hứa mỗi lần? Tôi đã nhìn thấy một số thư viện có một loại "chế độ hứa hẹn" như https://github.com/sindresorhus/got nhưng sau khi xem mã tôi vẫn không chắc chắn chính xác cách họ đã làm.

+0

này là những gì bạn đang tìm kiếm? https://github.com/kriskowal/q và https://www.npmjs.com/package/q –

+0

Tôi cũng không sử dụng thư viện Promise với nút 4.x phải không? –

+0

Tôi cho rằng có lẽ tôi chỉ cần trả lại Lời hứa mới trong mỗi phương pháp và cho phép tôi kết nối chúng bằng '.then'. Có đúng không? –

Trả lời

4

Bạn sử dụng chuỗi return this cho các cuộc gọi đồng bộ.

Bạn chuỗi sử dụng Promise hoặc gọi lại cho các cuộc gọi không đồng bộ.

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

Thú vị, vì vậy đó là sự kết hợp của 2. Tôi sẽ làm rối tung điều này. Cảm ơn –

+0

Có thể chuỗi không, ví dụ: 'myObject.set (...). Save(). Set (...)' bằng cách nào đó? Tôi đang cố gắng tìm ra cách để chuỗi bất kỳ phương pháp nào của lớp của tôi sang lớp khác, giống như bạn có thể làm trong PHP. Không chắc chắn nó có thể mặc dù. –

+0

PHP không phải là đa luồng hoặc trên vòng lặp sự kiện, do đó bạn không phải lo lắng về các phương thức * không đồng bộ * như JavaScript. Đó là một nhược điểm đối với PHP, vì bạn có thể lãng phí tài nguyên trong khi chờ đợi. Bạn sẽ phải sử dụng thư viện 'Promises' hoặc 'async' để xử lý mọi thứ. – TbWill4321

0

Bạn có thể lưu trữ một thành viên tư nhân đặc biệt biến __lastPromise. Ban đầu nó sẽ được giải quyết theo mặc định. Nhưng sau đó bất kỳ chức năng nào thực hiện nhiệm vụ sẽ cập nhật nó với lời hứa trả về. Và bản thân chức năng cũng sẽ chỉ thực hiện nhiệm vụ sautrước đó lời hứa được lưu trữ đã được giải quyết.

Như thế này:

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; 
} 

Toàn bộ lớp:

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

Tôi thực sự khuyên bạn không nên sử dụng phương pháp này trừ khi bạn cần phải sắp xếp tất cả các hoạt động của mình. – Bergi

Các vấn đề liên quan