tic
tic

Reputation: 2512

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

Upvotes: 1

Views: 55

Answers (2)

Mark
Mark

Reputation: 92440

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
  

Upvotes: 1

Daniel A. White
Daniel A. White

Reputation: 190907

I would avoid reassigning this.promise. I wouldn't make that a member of your class. You should just have your methods return the promise.

If you want to avoid using .then, look at using async/await.

Upvotes: 0

Related Questions