0

I have a recursive method which essentially increments a value until it reaches a maximum.

increase(delay) {
    return new Promise((resolve, reject) => {
        if (this.activeLeds < this.MAX_LEDS) {
            this.activeLeds++
            console.log(this.activeLeds)
        }
        return resolve()
    }).delay(delay).then(() => {
        if (this.activeLeds < this.MAX_LEDS) {
            this.increase(delay)
        } else {
            return Promise.resolve()
        }
    })
}

I'm testing some functionality and I want to know when the increase() method has been completed (aka resolved).

bounce(delay) {
    return new Promise((resolve, reject) => {
        this.increase(50).then(console.log('done'))
    })
}

However, I think I'm doing something wrong when I'm resolving the promise after

this.activeLeds < this.MAX_LEDS

is no longer true. I think it has something to do with the fact that I'm not resolving the original promise but I can't figure out how to fix it.

Nick
  • 2,862
  • 5
  • 34
  • 68
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) in `bounce`! – Bergi Oct 31 '17 at 20:19

1 Answers1

3

You were forgetting to return the result of the recursive call from the then callback, so it couldn't be awaited and the promise would just fulfill immediately.

Use

increase(delay) {
    if (this.activeLeds < this.MAX_LEDS) {
        this.activeLeds++
        console.log(this.activeLeds)
    }
    return Promise.delay(delay).then(() => {
        if (this.activeLeds < this.MAX_LEDS) {
            return this.increase(delay)
//          ^^^^^^
        }
    })
}

Btw, I would recommend to avoid testing the condition twice on every iteration, and also stop immediately without a delay even on the first call:

increase(delay) {
    if (this.activeLeds < this.MAX_LEDS) {
        this.activeLeds++
        console.log(this.activeLeds)
        return Promise.delay(delay).then(() => // implicit return from concise arrow body
            this.increase(delay)
        )
    } else {
        return Promise.resolve()
    }
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Oh wow, this really makes me rethink my understanding of promises. Very interesting. Anyway, it works. Will accept! – Nick Oct 31 '17 at 20:24