How To Delay Javascript Loop

Old approach

This code is what most have come up with

for (var index = 1; index < 50; index++) {
    setTimeout(function() {
    }, 100);    

Now this prints “50” fifty times, because a for-loop is synchronous while setTimout is asynchronous. This means that the for-loop is finished very fast and has started 50 setTimeouts. After 100ms all of those setTimeout functions will fire together, therefore printing “50” fifty times. Note that the var-keyword binds variables to the function scope, not the current block scope like in other languages.

In order to create a for-loop with actual delay – in our case printing a number, waiting 100ms and printing the next number – you need to create a self-invoking, recursive function. Don’t worry, it’s not that hard.

<span class="kwd">var</span><span class="pln"> maxLoops </span><span class="pun">=</span> <span class="lit">50</span><span class="pun">;</span> <span class="kwd">var</span><span class="pln"> counter </span><span class="pun">=</span> <span class="lit">0</span><span class="pun">;</span> <span class="pun">(</span><span class="kwd">function</span> <span class="kwd">next</span><span class="pun">()</span> <span class="pun">{</span> <span class="kwd">if</span> <span class="pun">(</span><span class="pln">counter</span><span class="pun">++</span> <span class="pun">></span><span class="pln"> maxLoops</span><span class="pun">)</span> <span class="kwd">return</span><span class="pun">;</span><span class="pln"> setTimeout</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">()</span> <span class="pun">{</span><span class="pln"> console</span><span class="pun">.</span><span class="pln">log</span><span class="pun">(</span><span class="pln">counter</span><span class="pun">);</span> <span class="kwd">next</span><span class="pun">();</span> <span class="pun">},</span> <span class="lit">100</span><span class="pun">);</span> <span class="pun">})();

Here we declare two variables, maxLoops and counter. These are for keeping track of how many times the function has called itself. Afterwards we create the function “next”, put it in brackets and call it immediately. This is why it’s called a self-invoking function.

The if-statement does two things. First of all it counts up our counter variable using the ++ operator. It also returns the function if it has been called 50 times, therefore stopping the loop.

The last part is the most important one. We create our setTimeout function and then call next() after the number has been printed. And that’s how you create a for-loop with delay in JavaScript.

New approach

While this post is still valid for ES5, I wanted to point out that there is now an easier method using async/await in the latest TypeScript 2.1.0 release. You can use this feature natively in the latest Node version, but TypeScript now allows you to compile async/await to ES5 for browsers.

You should still read the original post, especially if you found this blog entry while googling a similar problem.

<span class="kwd">
const</span><span class="pln"> delay </span><span class="pun">=</span> <span class="pun">(</span><span class="pln">amount</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">)</span> <span class="pun">=></span> <span class="pun">{</span> <span class="kwd">return</span> <span class="kwd">new</span> <span class="typ">Promise</span><span class="pun">((</span><span class="pln">resolve</span><span class="pun">)</span> <span class="pun">=></span> <span class="pun">{</span><span class="pln"> setTimeout</span><span class="pun">(</span><span class="pln">resolve</span><span class="pun">,</span><span class="pln"> amount</span><span class="pun">);</span> <span class="pun">});</span> <span class="pun">};</span><span class="pln"> async </span><span class="kwd">function</span><span class="pln"> loop</span><span class="pun">()</span> <span class="pun">{</span> <span class="kwd">for</span> <span class="pun">(</span><span class="pln">let i </span><span class="pun">=</span> <span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span> <span class="lit">50</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span> <span class="pun">{</span><span class="pln"> console</span><span class="pun">.</span><span class="pln">log</span><span class="pun">(</span><span class="pln">i</span><span class="pun">);</span><span class="pln"> await delay</span><span class="pun">(</span><span class="lit">100</span><span class="pun">);</span> <span class="pun">}</span> <span class="pun">}


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s