Search code examples
javascriptes6-promise

Promise does not resolve this


This simplified code:

class A {
  constructor() {
    this.promise = new Promise(async resolve => {
      this.resolve = resolve
    })
  }

  then() {
    this.promise.then(...arguments)
    this.resolve(this)
  }
}

const x = new A()
x.then(res => {
  console.log(res)
})

Fails to resolve.

If you change this.resolve(this) to this.resolve('done') it works. Any ideas why?


Solution

  • The item being returned (the this) has a .then method, and the Promise resolver (resolve) sees that, thinks that you called it with a Promise, so it tries to resolve that Promise as well:

    class A {
      constructor() {
        this.promise = new Promise(async resolve => {
          this.resolve = resolve
          await setTimeout(() => {
            this.x = 1
          }, 1000)
        })
      }
    
      then() {
        this.promise.then(...arguments)
        this.fin()
        console.log('then running');
      }
    
      fin() {
        this.resolve(this)
      }
    }
    
    const x = new A()
    x.then(res => {
      console.log(res)
    })

    One possible solution would be to call resolve with an object which wraps the this instead, so that the resolver function doesn't see the .then method and try to unwrap it as well:

    class A {
      constructor() {
        this.promise = new Promise(async resolve => {
          this.resolve = resolve
          await setTimeout(() => {
            this.x = 1
          }, 1000)
        })
      }
    
      then() {
        this.promise.then(...arguments)
        return this.fin();
      }
    
      fin() {
        this.resolve({ result: this })
      }
    }
    
    const x = new A()
    x.then(res => {
      console.log(res.result)
    })