Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript promises setTimeout

I'm currently working on a slot machine effect for a website. I use a function that calls itself several times with setTimeout(). I use setTimeout() and not a simple loop because I need the effect to slow down. This is where the milliseconds come in handy. After this i want to fire the same function with different parameters. So I need to know when the first "loop" is done. I tried promises for that. With no success.

To simplify the problem, can someone tell me why the code below doesn't fire the .then() method? I'm new to all this programming and this is my first question here. I hope it's not an obvious mistake I make here.

function countDown(i) {
  return promise = new Promise( (resolve, reject) => {

    console.log(i--);

    if (i > 0) {
      setTimeout( () => {
        countDown(i);
      }, 1000);
    } else {
      resolve('counter finished:');
    }

  });

}

let counter = countDown(10);
counter.then( (msg) => {
  console.log(msg);
});
like image 435
Simon Yazkaron Avatar asked Dec 10 '22 09:12

Simon Yazkaron


2 Answers

You simply need to resolve the promise after the recursive calls, like so:

function countDown(i) {
  return promise = new Promise( (resolve, reject) => {

    console.log(i--);

    if (i > 0) {
      setTimeout( () => {
        countDown(i).then(resolve);
      }, 1000);
    } else {
      resolve('counter finished:');
    }

  });

}

let counter = countDown(10);
counter.then( (msg) => {
  console.log(msg);
});
like image 111
mhodges Avatar answered Dec 21 '22 04:12

mhodges


You might want to look into using async / await, here is your example using this.

If you need to target old browser, you can also use something Babel / Typescript etc. But most modern browser already support this.

function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)) }

async function countDown(i) {
  while (i > 0) {
    console.log(i--);  
    await sleep(1000);
  }
  return "counter finished:";
}

let counter = countDown(10);
counter.then( (msg) => {
  console.log(msg);
});
like image 43
Keith Avatar answered Dec 21 '22 04:12

Keith