Search code examples
javascripthtmlcanvasdelaysetinterval

How to delay setInterval in Javascript?


I've been running into a weird problem repeatedly in JavaScript now. I can't seem to delay setInterval longer.

A small example of what happens:

var loop;
var count;
loop = setInterval(start, 30);

function start() {
    //Some code

    delay();

    //Some more code
}

function delay() {
    setTimeout(function () {
        count++;

        //Animation code

        if (count <= 1000) delay();
    }, 100);
}

Now what I want to do is, execute 'some code' part, do nothing while the 'animation code' executes, and then execute 'some more code' part.

What is happening is that the 'some more code' part and the delay function is getting executed simultaneously. I have tried clearInterval(loop) before calling the delay function and restarting it after the delay function completes it's execution, but the 'some more code' seems to get executed once anyways.

How can I get around this problem? Please give a detailed explanation with an example.


Solution

  • Your delay() function does not actually stop your start() function from completing.

    In Javascript, setTimeout() does not pause the execution of Javascript. Instead, what it does is schedule the callback passed to setTimeout() to run sometime in the future and the rest of your code just keeps on running.

    If you want to delay the execution of some block of code for some time period, then you have to put that block of code inside the setTimeout() callback like this:

    setTimeout(function() {
        // the code in here will run some time in the future
    }, delayTime);
    
    // the code here will run immediately
    

    The way this is often described in Javascript is to say that a call to setTimeout() is non-blocking. It doesn't stop or pause the running of the current thread of execution. In fact that thread of execution will run to completion. Instead, setTimeout() schedules a callback function to be called at a particular time in the future (when no other Javascript code is running).

    Because Javascript is single-threaded, it pretty much never works to loop to try to create a delay, even if you use a really long while() loop. The issue is that while you are looping, no other Javascript code can run so no other state can change so whatever loop condition you are waiting to change will not change while you are looping. This commonly just leads to a deadlock type of condition and eventually the browser realizes that the Javascript thread is "stuck" and will prompt to abort it.

    Instead, you program with events and future callbacks. You set up an event or timer callback so it can be called at some future time when something happens and then you put the relevant code in that callback or event handler. There are also more advanced tools to help manage this such as promises or async libraries, but they're just built on top of the same callback mechanism.