Search code examples
javascriptes6-promisees6-class

Chain promises in class without using .then


This is part of a larger problem, but how could I chain method calls on a class when they require a promise to resolve in order to get data.

The following will not work as when this.promise is being assigned each time, the function has already returned with this

class Test {
  constructor(promise) {
    this.promise = promise;
  }

  add(x) {
    this.promise.then(y => {
      this.promise = new Promise(resolve => {
        resolve(x + y);
      });
    });
    return this;
  }

  multiply(x) {
    this.promise.then(y => {
      this.promise = new Promise(resolve => {
        resolve(x * y);
      });
    });
    return this;
  }

  answer() {
    this.promise.then(x => {
      console.log(x);
    });
  }
}

function getNumber(num) {
 const promise = new Promise(resolve => {
   resolve(num);
 });
 return new Test(promise);
}

const num = getNumber(30);
num.add(20).multiply(2).answer();  // Outputs 33 instead of 100: (30 + 20) * 2

Solution

  • You can just reassign the result of then (which is another promise) to this.promise in the methods. This will ensure the this.promise is always the latest promise in the chain.

    class Test {
        constructor(promise) {
          this.promise = promise;
        }
      
        add(x) {
          const promise = this.promise.then(num => num + x)
          return new Test(promise);
        }
      
        multiply(x) {
          const promise = this.promise.then(num =>  x * num)
          return new Test(promise);
        }
      
        answer() {
          this.promise.then(console.log)
        }
      }
      
      function getNumber(num) {
       const promise = new Promise(resolve => {
         resolve(num);
       });
       return new Test(promise);
      }
      
      const num = getNumber(30);
      num.add(20).multiply(2).answer();  // Outputs 100: (30 + 20) * 2
      num.add(5).multiply(3).answer();  // Outputs 105: (30 + 5) * 3