Nick
Nick

Reputation: 2960

Create infinite loop with Promise recursion in NodeJS

I'm getting rid of my blocking infinite while loop and substituting it with promises. I have a simple run function which lights up an LED and turns it off after which it continues to the next one.

Obviously Promises don't work inside while loops so I was wondering how I can use recursion to go back into my run() function and also increment my counter x?

var x = 0
var sign = 1
function run() {
    return new Promise((resolve, reject) => {
        try {
            wait(20).then(() => { device.setColor("random", { 'channel': 0, 'index': x }) })
            wait(20).then(() => { device.setColor("#000000", { 'channel': 0, 'index': x }) })
            x += sign
            if (x == LED_COUNT - 1) {
                sign = -1
            } else if (x == 0) {
                sign = 1
            }
            return resolve()
        } catch (e) {
            return reject(e)
        }
    })
}
run() // this only runs once, I need it to run forever

Upvotes: 0

Views: 2258

Answers (3)

Amit Wagner
Amit Wagner

Reputation: 3264

not sure why you need a promise here.

var x = 0
var sign = 1

function run() {

    setTimeout(function () {
        device.setColor("random", {'channel': 0, 'index': x})
        device.setColor("#000000", {'channel': 0, 'index': x})
        if (x == LED_COUNT - 1) {
            sign = -1
        } else if (x == 0) {
            sign = 1
        }

        run()
    }, 20000)


}
run()

Upvotes: 1

Dalin Huang
Dalin Huang

Reputation: 11342

Recursive call:

add .then(run()) to the end of your promise.

not sure how your wait works, I'm using a setTimeout to delay each loop by 1 sec. the example below:

var x = 0
var sign = 1
function run() {
    return new Promise((resolve, reject) => {
        try {
            //example only
            console.log('x-->' + x);
            //wait(20).then(() => { device.setColor("random", { 'channel': 0, 'index': x }) })
            //wait(20).then(() => { device.setColor("#000000", { 'channel': 0, 'index': x }) })
            x += sign
            if (x == LED_COUNT - 1) {
                sign = -1
            } else if (x == 0) {
                sign = 1
            }
            return resolve()
        } catch (e) {
            return reject(e)
        }
    }).then(setTimeout(function(){ run() }, 1000));
}
run();

Upvotes: 2

MinusFour
MinusFour

Reputation: 14423

I'd assume you'd want to wait for both promises and then run it again right? Here's a way you could try it. If you have access to Promise.try use that instead of Promise.resolve().then(...

var x = 0
var sign = 1

function run() {
  return Promise.resolve().then(function() {
    x += sign
    if (x == LED_COUNT - 1) {
      sign = -1
    } else if (x == 0) {
      sign = 1
    }
    return Promise.all([
      wait(20).then(() => {
        device.setColor("random", {
          'channel': 0,
          'index': x
        })
      }),
      wait(20).then(() => {
        device.setColor("#000000", {
          'channel': 0,
          'index': x
        })
      })
    ]);
  }).then(run);
}
run()

You could also just group both of them in one function and only use one wait(20) promise:

return wait(20).then(() => {
    device.setColor("random", {
        'channel': 0,
        'index': x
    });
    device.setColor("#000000", {
        'channel': 0,
        'index': x
    });
})

Upvotes: 0

Related Questions