Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is clearTimeout necessary after setTimeout with 0ms?

As i have already learned (here: https://www.youtube.com/watch?v=8aGhZQkoFbQ) it can be useful in some cases to call a setTimeout with 0ms delay (because of the event loop).

Now ususally whenever I use setTimeout I also take care to call clearTimeout at the appropriate spot to make sure nothing remains somewhere and gets executed at a point where I do not want it to be executed.

So my question is: Is it necessary (does it make sense) to call clearTimeout after a setTimeout with 0ms? The passed function is immediately appended to the callback queue so I would assume clearTimeout does not (and cannot) do anything. Or can clearTimeout remove the passed function even from the callback queue (so after the timeout expired but before the function has been executed)?

Second question: Even if it does not do anything, is it anyway 'best practice' to call clearTimeout always in those cases?

like image 977
nothing9 Avatar asked Sep 15 '15 08:09

nothing9


People also ask

Is clearTimeout necessary?

You don't actually need to use clearTimeout , you only use it if you wish to cancel the timeout you already set before it happens. It's usually more practical to use clearInterval with setInterval because setInterval usually runs indefinitely.

Can I use clearTimeout inside setTimeout?

It's worth noting that the pool of IDs used by setTimeout() and setInterval() are shared, which means you can technically use clearTimeout() and clearInterval() interchangeably.

How does setTimeout and clearTimeout work?

setTimeout() executes the passed function after given time. The number id value returned by setTimeout() function is stored in a variable and it's passed into the clearTimeout() function to clear the timer.

What is the purpose of clearTimeout method?

The clearTimeout() method clears a timer set with the setTimeout() method.


1 Answers

Is it necessary (does it make sense) to call clearTimeout after a setTimeout with 0ms?

It is necessary if the goal is to prevent the asynchronous timer callback from running. The execution ordering can be discussed entirely in terms of when the callback is invoked.

First off, the value of 0 milliseconds as a delay means 'run the callback as soon as possible' (from an future asynchronous context), but:

  1. it does not change how setTimeout works; and

  2. 0 is not the actual value used anyway.

The passed function is immediately appended to the callback queue so I would assume clearTimeout does not (and cannot) do anything.

This is incorrect. The passed function is not "immediately appended to the callback queue". Rather, when the timeout expires and the timer is still active, the callback function will be invoked. There may be other asynchronous callbacks - from timers or otherwise - that could be run prior.

Also, all remaining synchronous code is guaranteed to run before the timer callback occurs: clearing the timeout in this context prevents the timer callback from ever being called, irrespective of the time taken in the synchronous code.

Even if it does not do anything, is it anyway 'best practice' to call clearTimeout always in those cases?

Calling clearTimeout will either

  1. prevent the callback from executing, if cleared prior to the callback (as it removes the timer), or;

  2. do nothing if the callback has already occurred (as the timer is no longer active)

Thus clearing the timer is required for correct functioning of the code/algorithm; or it is a useless operation. Creating a timer only to immediately cancel it may be pointless, but that's a digression about code structure..

I also take care to call clearTimeout at the appropriate spot to make sure nothing remains somewhere and gets executed at a point where I do not want it to be executed.

As per above, there is no need to manually clear a timer that is no longer active; and cancelling a timer prior to the invocation of the timer callback will remove the timer and thus prevent the timer callback from executing.

When/where/if a timer should be cancelled depends on the design as a whole.


Cancelling the timeout in the executing code prevents the callback from running: neither the "A" or "B" callback will run.

a = setTimeout(function () { console.log("A"); }, 0);
clearTimeout(a);

b = setTimeout(function () { console.log("B"); }, 0);
s = Date.now()
while (Date.now() - s < 100) { /* waste 100ms of CPU */ }
clearTimeout(b);

Cancelling the timeout in an asynchronous event that runs first prevents the callback from running: the "B" callback will never run:.

a = setTimeout(function () { console.log("A"); clearTimeout(b); }, 0);
b = setTimeout(function () { console.log("B"); }, 0);

While a secondary timer is used (as the ordering is well guaranteed), there is a chance that other asynchronous events (button clicks, web workers, AJAX, etc.) could also occur before a "0ms" timeout.

A clearTimeout invoked after the callback (from any context) is useless:

a = setTimeout(function () { console.log("A"); clearTimeout(a); }, 0);

a = setTimeout(function () { console.log("A"); }, 0);
b = setTimeout(function () { console.log("B"); clearTimeout(a); }, 0);
like image 149
user2864740 Avatar answered Sep 19 '22 05:09

user2864740