TrevTheDev
TrevTheDev

Reputation: 2737

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?

Upvotes: 0

Views: 62

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370619

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)
})

Upvotes: 2

Related Questions