Search code examples
javascriptnode.jsclassecmascript-6chaining

How to chain async methods in javascript ES6 classes


I want to chain methods from a class. I have o problems with synchronous methods, but I don't know how to do it with asynchronous methods.

For example, this class:

class Example {

  constructor() {
    this.val = 0
  }

  async () {
    setTimeout(() => {
      this.val += 1
      return this
    }, 5000)
  }

  sync () {
    this.val += 1
    return this
  }

  check () {
    console.log('checker', this.val)
    return this
  }

}

This works:

new Example().sync().check()
> 1

But this doesn't work:

new Example().async().check()
> TypeError: Cannot read property 'check' of undefined

P.S. I want chaining, not Hell Callbacks.


Solution

  • I expect that you want to call check() after the timeout has expired. The problem is that forks off, and you can't immediately have something available to return.

    You could pass in check() as a callback:

    class Example {
    
      constructor() {
        this.val = 0
      }
    
      async (callback) {
        setTimeout(() => {
          this.val += 1
          callback()
        }, 5000)
      }
    
      sync () {
        this.val += 1
        return this
      }
    
      check () {
        console.log('checker', this.val)
        return this
      }
    
    }
    
    // execution
    var ex = new Example();
    ex.async(ex.check)
    

    ... or a promise

    class Example {
    
      constructor() {
        this.val = 0
      }
    
      async (callback) {
        var deferred = Q.defer()
        setTimeout(() => {
          this.val += 1
          deferred.resolve();
        }, 5000)
        return deferred.promise;
      }
    
      sync () {
        this.val += 1
        return this
      }
    
      check () {
        console.log('checker', this.val)
        return this
      }
    
    }
    
    // execution
    var ex = new Example()
    ex.async().then(() => ex.check())
    

    ... Or you could use ES6 generators