Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding javascript promise used with setTimeout and setInterval

Can someone help me understand these 2 lines of code and improve them to actually allow me to stop the repeats?

var wait = ms => new Promise(r => setTimeout(r, ms));
var repeat = (ms, func) => new Promise(r => (setInterval(func, ms), wait(ms).then(r)));

repeat(1000, () => Promise.all([myfunction()])
  .then(...)
like image 827
zabumba Avatar asked May 14 '26 08:05

zabumba


2 Answers

The first line (wait) simply waits a certain number of milliseconds and then ends.

The second line (repeat) programs a function to be run in a certain interval of time (setInterval), and then calls wait and passes the number of milliseconds set on repeat function to it. These function are called only once. Javascript's internal controls for setInterval is what takes control from now on calling () => Promise.all([myfunction()]) at the programmed time interval.

If you just ident your code things get clearer.

var wait = 
    ms => new Promise(
        r => setTimeout(r, ms)
    );

var repeat = 
    (ms, func) => new Promise(
        r => (
            setInterval(func, ms), 
            wait(ms).then(r)
        )
    );

repeat(1000, () => Promise.all([myfunction()]))
.then(...);

In order to stop the function you have to capture the interval's id and call clearInterval as SimpleJ pointed out. You probably will want to do this with Promises once you're all into it. So a complete working example would be:

var intervalID = 0;

var wait = 
    ms => new Promise(
        r => setTimeout(r, ms)
    );

var repeat = 
    (ms, func) => new Promise(
        r => (
            intervalID = setInterval(func, ms), 
            wait(ms).then(r)
        )
    );

var myfunction = 
    () => new Promise(
        r => r(console.log('repeating...'))
    );

var stopAfter5Secs = 
    () => new Promise(
        r => r(setTimeout(() => { 
                    clearInterval(intervalID);
                    console.log('repeat end') 
               } , 5000))
    );

repeat(1000, () => Promise.all([myfunction()])) // 1000 miliseconds = 1 second
.then(stopAfter5Secs())  // starts timer to end repetitions
.then(console.log('repeat start')); // informs that all actions were started correctly and we are waiting for them to finish

Promiss.all calls all promisses in any interable object passed to it. In this case an array with only one element (myfunction). I created a simple function which only writes 'repeating' to the console, to be that function. But you can pass any number of functions you want to it if all of them return promisses.

You can see it working here: https://jsfiddle.net/9n2knxdg/7/

like image 183
Nelson Teixeira Avatar answered May 15 '26 23:05

Nelson Teixeira


You could resolve the interval returned from setInterval once wait finishes in repeat and clear the interval with clearInterval:

var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

var repeat = (ms, func) => new Promise((resolve) => {
  const interval = setInterval(func, ms);
  wait(ms).then(() => resolve(interval));
});

repeat(1000, () => console.log("Repeated"))
  .then((interval) => {
    console.log("Stopping repeat");
    clearInterval(interval);
  });

Although I'm not sure I understand the purpose of the repeat function.

like image 33
SimpleJ Avatar answered May 15 '26 21:05

SimpleJ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!