3

Say I have a function render which runs client side, and can take 100-1000ms And I have a function fetch that makes a server request and on success, clears timeout for render and then calls render with a timeout of 100ms. And I have a button, which onclick, again, clears the timeout for render and then calls render with a timeout of 100ms.

I've found when I try to click the button many times and also if many server requests had been made, only the first and last response cause render, as expected. But is this guaranteed? Can I safely rely on this?

Any links that reassure me or tell me about gotchas will be appreciated. I've been through this I understand that whatever be the case, if any asyc event occurs, it will be queued and executed only the first time execution goes idle, but I'm confused about the decision about what should be in the queue since that's done by the browser?

Community
  • 1
  • 1
lmc
  • 420
  • 2
  • 11

2 Answers2

0

I had trouble finding a good source, so I tried running this script in my browser.

var doItLater = function () {
    alert("I did it!");
};

window.onload = function () {
    // set a timeout to execute immediately
    var timeout = window.setTimeout(doItLater, 0);

    for (var i = 0; i < 1000000000; i++) {
        // waste some time
    }
    // The timeout has definitely triggered by now.
    // doItLater is queued up to execute as soon as
    // this function returns.

    clearTimeout(timeout); // wait, I changed my mind!
};

// Does doItLater get called?

And it works! clearTimeout() prevents doItLater() from being called, even though it's been placed on the queue already.

On a side note, I would definitely recommend using setTimeout() within your render function to prevent the page from becoming unresponsive. 1000 ms is way too long for a function to block the event loop. (for example, see here)

Community
  • 1
  • 1
NPH
  • 103
  • 4
0

I think this is JS-runtime implementation-specific. For example, this SO question suggests that on IE it is possible for a timeout callback to execute even after clearTimeout() has been called for it.

Given the single-threaded nature of JS event chain I recommend to have a control flag which you set before or after you call clearTimeout() and check for that flag in the timeout callback:

var isActive = true;
var timerId = setTimeout(function() {
    if (!isActive) return;
    // doStuff
}, someInterval);

...

function onSomeExternalEvent() {
    isActive = false;
    clearTimeout(timerId);
}
Community
  • 1
  • 1
Boris B.
  • 4,933
  • 1
  • 28
  • 59