2024-01-10

setTimeout and setInterval extra arguments

If I'm spending my days on LinkedIn, I might as well share some knowledge. Let's start with something useless (I hadn't have a chance to use it myself anywhere so far).

A still little known fact is that both setInterval and setTimeout accept more than two arguments (first the callback, then the time). Each next argument will be passed as an argument to the callback.

Let's imagine a purely hypothetical situation where we want to console.log 100 foos and 1 bar in 1 second intervals and then stop the process. Normally, people would keep the counter *outside* of the setInterval call. However, it's possible to pass an object as an argument to the callback, and because objects in JavaScript are passed as references, it will be the same object every time (for that reason, we cannot use a primitive value; if we passed just 0, it would be zero every time). Now we can read the counter prop in line 2 and bump it in line 4, and thanks to the nature of closures, no one outside will be able to interfere with that. Hence, we now have an interval with truly private, and thus safe, data. How cool is that?

const intervalId = setInterval(function (data) {
    if (data.counter < 100) {
        console.log('foo');
        data.counter++;
    } else {
        console.log('bar');
        clearInterval(intervalId);
    }
}, 1_000, { counter: 0 });
//        ^^^^^^^^^^^^^^ this is where `data` is created

The only thing that we cannot contain this way is the interval id, but we might want to allow other actors to clear it. If not, a thunk would be an option. But that's perhaps for our next episode.

Don't forget to like and subscribe.