0

I have a quick question about using recursive setTimeOut recursively and a clearTimeOut that get called somewhere else.

On rare cases, will there ever gonna be a bug where clearTimeOut doesn't actually stop the loop? Is it possible that the timeOutID get changes into a new value and clearTimeout is called on the old value?

Here is the code:

timeOutID = 0;

function timeOutRecusive() {
    timeOutID = setTimeout('timeOutRecusive();', 1000);
}

function killTimeOutRecusive() {
    clearTimeout(timeOutID);
}

//when page started.
start() {
    timeOutRecusive();
}

//When a button is press, calls killTimeOutRecursive();

EDIT: I have some typo in my code. It should be 'timeOutID' instead of clockID. clearTimeOut should be 'clearTimeout' (using its built-in)

Michael Lihs
  • 7,460
  • 17
  • 52
  • 85
anh
  • 11
  • 2
  • 1
    There is no built-in function named `clearTimeOut`... – CertainPerformance Oct 30 '18 at 22:08
  • Much like `setTimeout`, it's `clearTimeout` and not `clearTimeOut`. Also, `clockID` is never defined anywhere. – Madara's Ghost Oct 30 '18 at 22:08
  • 1
    As long as you're correctly referencing the timeout id, and correctly updating it each time you start the next one, and never start a second set of them using the same variable, it should work. but that's a lot of "if"'s. – Kevin B Oct 30 '18 at 22:09
  • You also seem to be calling `killTimeOutRecursive` at a rather odd time. – Kevin B Oct 30 '18 at 22:17
  • @KevinB i have updated the codoe. killTimeOOut shouold be called when a user press the button from a webpage – anh Oct 30 '18 at 22:19
  • Rather than passing a string to *setTimeout*, pass a function reference, i.e. replace `setTimeout('timeOutRecusive();', 1000)` with `setTimeout(timeOutRecusive, 1000)`. Should *timeOutRecusive* be *timeOutRecursive*? – RobG Oct 30 '18 at 22:27
  • @RobG that will be more efficient, but not related to my question. – anh Oct 30 '18 at 22:31
  • @anh—hence it's a comment. ;-) – RobG Oct 30 '18 at 22:32
  • @RobG I see. Thanks for suggestion :) – anh Oct 30 '18 at 22:33

3 Answers3

1

This approach is pretty bullet-proof, and a standard practice.

Is it possible that the timeoutId get changes into a new value and clearTimeout is called on the old value?

No, this is not possible. JS code doesn't run in parallel, there are no data races from multithreading.

The only edge case where killTimeoutRecursive does not work as expected is when it is called from within timeoutRecursive, after the old timeout occurred and before the new one was created:

var timeoutId = 0;
function timeoutRecusive() {
    callback();
    timeoutId = setTimeout(timeOutRecusive, 1000);
}

function killTimeoutRecusive() {
    clearTimeout(timeoutId);
}

function callback() { // this might be user-provided
    killTimeoutRecursive();
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

Your thought is legit. If the callback method of the specified timeout would be called in a parallel execution, it could just create a new timeout (not yet updated the variable) while you try to clear the current timeout.

However, the timeout handling is executed sequential. (thats why it some times can take way longer than 1000ms for the callback to be fired)

Meaning:

-If your code is just about to create a new timeout, your clear call "waits" and then clears the 3ms old timer.

-If you are just about to clear the timeout, when 1000 ms have elapsed, the callback will not be fired, as long as your code is busy. And when its cleared, it wont be added to the event queue anymore, when the timeout is executed after delayed 1004ms.

dognose
  • 20,360
  • 9
  • 61
  • 107
-1

No.

Ignoring the fact there is no clearTimeOut function (it's clearTimeout) and it's being called with clockID, not timeOutID), all of these statements will be run sequentially; any tasks that setTimeout and friends might run will be only run after the current synchronous block of JavaScript is run, i.e. the sequence would be something like

[frame]
  start()
  setTimeout(...)
  clearTimeout(...)
[frame]
  (this is where timeout functions could be run)
AKX
  • 152,115
  • 15
  • 115
  • 172