Reputation: 2737
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
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