Search code examples
javascriptnode.jsdesign-patternses6-promise

Method chaining with Promises


I want to implement the classic method chain pattern, the final usage should be

DB
  .push(2)
  .push(3)

This is the current code, obviously doesn't work, I'm not clear how to return the reference to DB itself resolving the promise

let nodes = [];
let DB = {
    self:this,
    push: (i) => new Promise((resolve, reject) => {
        nodes.push(i)
        resolve(this)
    })
}

Solution

  • Only a class or function instance has a this reference.

    class DB {
      constructor() {
        this.nodes = [];
        this.promise = Promise.resolve();
      }
      push(i) {
        this.nodes.push(i);
        return this;
      }
      pushAsync(i) {
        return new Promise((resolve) => {
          this.nodes.push(i);
          resolve();
        });
      }
      pushAsyncChain(i) {
        this.promise.then(() => {
          this.promise = new Promise((resolve) => {
            this.nodes.push(i);
            resolve();
          });
        });
        return this;
      }
      then(callback) {
        this.promise.then(callback);
      }
    }
    
    const db = new DB();
    db.push(2).push(3);
    db.pushAsync(4).then(() => db.pushAsync(5));
    db
      .pushAsyncChain(6)
      .pushAsyncChain(7)
      .then(() => console.log(db.nodes)); // or await db.promise; console.log(db.nodes);