[javascript] How do I add a delay in a JavaScript loop?

I would like to add a delay/sleep inside a while loop:

I tried it like this:

alert('hi');

for(var start = 1; start < 10; start++) {
  setTimeout(function () {
    alert('hello');
  }, 3000);
}

Only the first scenario is true: after showing alert('hi'), it will be waiting for 3 seconds then alert('hello') will be displayed but then alert('hello') will be repeatedly constantly.

What I would like is that after alert('hello') is shown 3 seconds after alert('hi') then it needs to wait for 3 seconds for the second time alert('hello') and so on.

This question is related to javascript loops sleep

The answer is


This script works for most things

function timer(start) {
    setTimeout(function () { //The timer
        alert('hello');
    }, start*3000); //needs the "start*" or else all the timers will run at 3000ms
}

for(var start = 1; start < 10; start++) {
    timer(start);
}

Just thought I'd post my two cents here as well. This function runs an iterative loop with a delay. See this jsfiddle. The function is as follows:

function timeout(range, time, callback){
    var i = range[0];                
    callback(i);
    Loop();
    function Loop(){
        setTimeout(function(){
            i++;
            if (i<range[1]){
                callback(i);
                Loop();
            }
        }, time*1000)
    } 
}

For example:

//This function prints the loop number every second
timeout([0, 5], 1, function(i){
    console.log(i);
});

Would be equivalent to:

//This function prints the loop number instantly
for (var i = 0; i<5; i++){
    console.log(i);
}

_x000D_
_x000D_
function waitforme(ms)  {

return new Promise( resolve => {

    setTimeout(()=> {resolve('')} ,ms );


})


}



async function printy()  {




for (let i= 0; i < 10 ; ++i)    {


    await waitforme(1000);
    //wait for 500 milisecond

    console.log(i);


}


console.log("I Ran after the loop finished :)");
}


printy();
_x000D_
_x000D_
_x000D_


In ES6 (ECMAScript 2015) you can iterate with delay with generator and interval.

Generators, a new feature of ECMAScript 6, are functions that can be paused and resumed. Calling genFunc does not execute it. Instead, it returns a so-called generator object that lets us control genFunc’s execution. genFunc() is initially suspended at the beginning of its body. The method genObj.next() continues the execution of genFunc, until the next yield. (Exploring ES6)


Code example:

_x000D_
_x000D_
let arr = [1, 2, 3, 'b'];_x000D_
let genObj = genFunc();_x000D_
_x000D_
let val = genObj.next();_x000D_
console.log(val.value);_x000D_
_x000D_
let interval = setInterval(() => {_x000D_
  val = genObj.next();_x000D_
  _x000D_
  if (val.done) {_x000D_
    clearInterval(interval);_x000D_
  } else {_x000D_
    console.log(val.value);_x000D_
  }_x000D_
}, 1000);_x000D_
_x000D_
function* genFunc() {_x000D_
  for(let item of arr) {_x000D_
    yield item;_x000D_
  }_x000D_
}
_x000D_
_x000D_
_x000D_

So if you are using ES6, that the most elegant way to achieve loop with delay (for my opinion).


Just try this

 var arr = ['A','B','C'];
 (function customLoop (arr, i) {
    setTimeout(function () {
    // Do here what you want to do.......
    console.log(arr[i]);
    if (--i) {                
      customLoop(arr, i); 
    }
  }, 2000);
})(arr, arr.length);

Result

A // after 2s
B // after 2s
C // after 2s

Another way is to multiply the time to timeout, but note that this is not like sleep. Code after the loop will be executed immediately, only the execution of the callback function is deferred.

for (var start = 1; start < 10; start++)
    setTimeout(function () { alert('hello');  }, 3000 * start);

The first timeout will be set to 3000 * 1, the second to 3000 * 2 and so on.


Simple implementation of showing a piece of text every two seconds as long the loop is running.

for (var i = 0; i < foo.length; i++) {
   setInterval(function(){ 
     console.log("I will appear every 2 seconds"); 
   }, 2000);
  break;
};

I do this with Bluebird’s Promise.delay and recursion.

_x000D_
_x000D_
function myLoop(i) {_x000D_
  return Promise.delay(1000)_x000D_
    .then(function() {_x000D_
      if (i > 0) {_x000D_
        alert('hello');_x000D_
        return myLoop(i -= 1);_x000D_
      }_x000D_
    });_x000D_
}_x000D_
_x000D_
myLoop(3);
_x000D_
<script src="//cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.4/bluebird.min.js"></script>
_x000D_
_x000D_
_x000D_


   let counter =1;
   for(let item in items) {
        counter++;
        setTimeout(()=>{
          //your code
        },counter*5000); //5Sec delay between each iteration
    }

You can use RxJS interval operator. Interval emits integer every x number of seconds, and take is specify number of times it has to emit numberss

_x000D_
_x000D_
Rx.Observable_x000D_
  .interval(1000)_x000D_
  .take(10)_x000D_
  .subscribe((x) => console.log(x))
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.lite.min.js"></script>
_x000D_
_x000D_
_x000D_


I think you need something like this:

var TimedQueue = function(defaultDelay){
    this.queue = [];
    this.index = 0;
    this.defaultDelay = defaultDelay || 3000;
};

TimedQueue.prototype = {
    add: function(fn, delay){
        this.queue.push({
            fn: fn,
            delay: delay
        });
    },
    run: function(index){
        (index || index === 0) && (this.index = index);
        this.next();
    },
    next: function(){
        var self = this
        , i = this.index++
        , at = this.queue[i]
        , next = this.queue[this.index]
        if(!at) return;
        at.fn();
        next && setTimeout(function(){
            self.next();
        }, next.delay||this.defaultDelay);
    },
    reset: function(){
        this.index = 0;
    }
}

Test code:

var now = +new Date();

var x = new TimedQueue(2000);

x.add(function(){
    console.log('hey');
    console.log(+new Date() - now);
});
x.add(function(){
    console.log('ho');
    console.log(+new Date() - now);
}, 3000);
x.add(function(){
    console.log('bye');
    console.log(+new Date() - now);
});

x.run();

Note: using alerts stalls javascript execution till you close the alert. It might be more code than you asked for, but this is a robust reusable solution.


for common use "forget normal loops" and use this combination of "setInterval" includes "setTimeOut"s: like this (from my real tasks).

        function iAsk(lvl){
            var i=0;
            var intr =setInterval(function(){ // start the loop 
                i++; // increment it
                if(i>lvl){ // check if the end round reached.
                    clearInterval(intr);
                    return;
                }
                setTimeout(function(){
                    $(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond
                },50);
                setTimeout(function(){
                     // do another bla bla bla after 100 millisecond.
                    seq[i-1]=(Math.ceil(Math.random()*4)).toString();
                    $("#hh").after('<br>'+i + ' : rand= '+(Math.ceil(Math.random()*4)).toString()+' > '+seq[i-1]);
                    $("#d"+seq[i-1]).prop("src",pGif);
                    var d =document.getElementById('aud');
                    d.play();                   
                },100);
                setTimeout(function(){
                    // keep adding bla bla bla till you done :)
                    $("#d"+seq[i-1]).prop("src",pPng);
                },900);
            },1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions)
        }

PS: Understand that the real behavior of (setTimeOut): they all will start in same time "the three bla bla bla will start counting down in the same moment" so make a different timeout to arrange the execution.

PS 2: the example for timing loop, but for a reaction loops you can use events, promise async await ..


To my knowledge the setTimeout function is called asynchronously. What you can do is wrap the entire loop within an async function and await a Promise that contains the setTimeout as shown:

var looper = async function () {
  for (var start = 1; start < 10; start++) {
    await new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log("iteration: " + start.toString());
        resolve(true);
      }, 1000);
    });
  }
  return true;
}

And then you call run it like so:

looper().then(function(){
  console.log("DONE!")
});

Please take some time to get a good understanding of asynchronous programming.


In ES6 you can do as following:

_x000D_
_x000D_
 for (let i = 0; i <= 10; i++){       _x000D_
     setTimeout(function () {   _x000D_
        console.log(i);_x000D_
     }, i*3000)_x000D_
 }
_x000D_
_x000D_
_x000D_

In ES5 you can do as:

_x000D_
_x000D_
for (var i = 0; i <= 10; i++){_x000D_
   (function(i) {          _x000D_
     setTimeout(function () {   _x000D_
        console.log(i);_x000D_
     }, i*3000)_x000D_
   })(i);  _x000D_
 }
_x000D_
_x000D_
_x000D_

The reason is, let allows you to declare variables that are limited to a scope of a block statement, or expression on which it is used, unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.


/* 
  Use Recursive  and setTimeout 
  call below function will run loop loopFunctionNeedCheck until 
  conditionCheckAfterRunFn = true, if conditionCheckAfterRunFn == false : delay 
  reRunAfterMs miliseconds and continue loop
  tested code, thanks
*/

function functionRepeatUntilConditionTrue(reRunAfterMs, conditionCheckAfterRunFn,
 loopFunctionNeedCheck) {
    loopFunctionNeedCheck();
    var result = conditionCheckAfterRunFn();
    //check after run
    if (!result) {
        setTimeout(function () {
            functionRepeatUntilConditionTrue(reRunAfterMs, conditionCheckAfterRunFn, loopFunctionNeedCheck)
        }, reRunAfterMs);
    }
    else  console.log("completed, thanks");    
            //if you need call a function after completed add code call callback in here
}

//passing-parameters-to-a-callback-function
// From Prototype.js 
if (!Function.prototype.bind) { // check if native implementation available
    Function.prototype.bind = function () {
        var fn = this, args = Array.prototype.slice.call(arguments),
            object = args.shift();
        return function () {
            return fn.apply(object,
              args.concat(Array.prototype.slice.call(arguments)));
        };
    };
}

//test code: 
var result = 0; 
console.log("---> init result is " + result);
var functionNeedRun = function (step) {           
   result+=step;    
       console.log("current result is " + result);  
}
var checkResultFunction = function () {
    return result==100;
}  

//call this function will run loop functionNeedRun and delay 500 miliseconds until result=100    
functionRepeatUntilConditionTrue(500, checkResultFunction , functionNeedRun.bind(null, 5));

//result log from console:
/*
---> init result is 0
current result is 5
undefined
current result is 10
current result is 15
current result is 20
current result is 25
current result is 30
current result is 35
current result is 40
current result is 45
current result is 50
current result is 55
current result is 60
current result is 65
current result is 70
current result is 75
current result is 80
current result is 85
current result is 90
current result is 95
current result is 100
completed, thanks
*/

Since ES7 theres a better way to await a loop:

// Returns a Promise that resolves after "ms" Milliseconds
const timer = ms => new Promise(res => setTimeout(res, ms))

async function load () { // We need to wrap the loop into an async function for this to work
  for (var i = 0; i < 3; i++) {
    console.log(i);
    await timer(3000); // then the created Promise can be awaited
  }
}

load();

When the engine reaches the await part, it sets a timeout and halts the execution of the async function. Then when the timeout completes, execution continues at that point. That's quite useful as you can delay (1) nested loops, (2) conditionally, (3) nested functions:

_x000D_
_x000D_
async function task(i) { // 3
  await timer(1000);
  console.log(`Task ${i} done!`);
}

async function main() {
  for(let i = 0; i < 100; i+= 10) {
    for(let j = 0; j < 10; j++) { // 1
      if(j % 2) { // 2
        await task(i + j);
      }
    }
  }
}
    
main();

function timer(ms) { return new Promise(res => setTimeout(res, ms)); }
_x000D_
_x000D_
_x000D_

Reference on MDN

While ES7 is now supported by NodeJS and modern browsers, you might want to transpile it with BabelJS so that it runs everywhere.


I would probably use setInteval. Like this,

var period = 1000; // ms
var endTime = 10000;  // ms
var counter = 0;
var sleepyAlert = setInterval(function(){
    alert('Hello');
    if(counter === endTime){
       clearInterval(sleepyAlert);
    }
    counter += period;
}, period);

This will work

for (var i = 0; i < 10; i++) {
  (function(i) {
    setTimeout(function() { console.log(i); }, 100 * i);
  })(i);
}

Try this fiddle: https://jsfiddle.net/wgdx8zqq/


Here is a function that I use for looping over an array:

function loopOnArrayWithDelay(theArray, delayAmount, i, theFunction, onComplete){

    if (i < theArray.length && typeof delayAmount == 'number'){

        console.log("i "+i);

        theFunction(theArray[i], i);

        setTimeout(function(){

            loopOnArrayWithDelay(theArray, delayAmount, (i+1), theFunction, onComplete)}, delayAmount);
    }else{

        onComplete(i);
    }
}

You use it like this:

loopOnArrayWithDelay(YourArray, 1000, 0, function(e, i){
    //Do something with item
}, function(i){
    //Do something once loop has completed
}

Here is how I created an infinite loop with a delay that breaks on a certain condition:

  // Now continuously check the app status until it's completed, 
  // failed or times out. The isFinished() will throw exception if
  // there is a failure.
  while (true) {
    let status = await this.api.getStatus(appId);
    if (isFinished(status)) {
      break;
    } else {
      // Delay before running the next loop iteration:
      await new Promise(resolve => setTimeout(resolve, 3000));
    }
  }

The key here is to create a new Promise that resolves by timeout, and to await for its resolution.

Obviously you need async/await support for that. Works in Node 8.


In my opinion, the simpler and most elegant way to add a delay in a loop is like this:

names = ['John', 'Ana', 'Mary'];

names.forEach((name, i) => {
 setTimeout(() => {
  console.log(name);
 }, i * 1000);  // one sec interval
});

Try this

//the code will execute in 1 3 5 7 9 seconds later
function exec(){
  for(var i=0;i<5;i++){
   setTimeout(function(){
     console.log(new Date());   //It's you code
   },(i+i+1)*1000);
  }
}

In addition to the accepted answer from 10 years ago, with more modern Javascript one can use async/await/Promise() or generator function to achieve the correct behavior. (The incorrect behavior suggested in other answers would be setting series of 3 seconds alerts regardless of "accepting" the alert() - or finishing the task at hand)

Using async/await/Promise():

_x000D_
_x000D_
alert('hi');

(async () => {
  for(let start = 1; start < 10; start++) {
    await new Promise(resolve => setTimeout(() => {
      alert('hello');
      resolve();
    }, 3000));
  }
})();
_x000D_
_x000D_
_x000D_

Using a generator function:

_x000D_
_x000D_
alert('hi');

let func;

(func = (function*() {
  for(let start = 1; start < 10; start++) {
    yield setTimeout(() => {
      alert('hello');
      func.next();
    }, 3000);
  }
})()).next();
_x000D_
_x000D_
_x000D_


A function-less solution

I am a bit late to the party, but there is a solution without using any functions:

alert('hi');

for(var start = 1; start < 10; start++) {
  setTimeout(() => alert('hello'), 3000 * start);
}

_x000D_
_x000D_
    var startIndex = 0;_x000D_
    var data = [1, 2, 3];_x000D_
    var timeout = 1000;_x000D_
_x000D_
    function functionToRun(i, length) {_x000D_
      alert(data[i]);_x000D_
    }_x000D_
_x000D_
    (function forWithDelay(i, length, fn, delay) {_x000D_
      setTimeout(function() {_x000D_
        fn(i, length);_x000D_
        i++;_x000D_
        if (i < length) {_x000D_
          forWithDelay(i, length, fn, delay);_x000D_
        }_x000D_
      }, delay);_x000D_
    })(startIndex, data.length, functionToRun, timeout);
_x000D_
_x000D_
_x000D_

A modified version of Daniel Vassallo's answer, with variables extracted into parameters to make the function more reusable:

First let's define some essential variables:

var startIndex = 0;
var data = [1, 2, 3];
var timeout = 3000;

Next you should define the function you want to run. This will get passed i, the current index of the loop and the length of the loop, in case you need it:

function functionToRun(i, length) {
    alert(data[i]);
}

Self-executing version

(function forWithDelay(i, length, fn, delay) {
   setTimeout(function () {
      fn(i, length);
      i++;
      if (i < length) {
         forWithDelay(i, length, fn, delay); 
      }
  }, delay);
})(startIndex, data.length, functionToRun, timeout);

Functional version

function forWithDelay(i, length, fn, delay) {
   setTimeout(function () {
      fn(i, length);
      i++;
      if (i < length) {
         forWithDelay(i, length, fn, delay); 
      }
  }, delay);
}

forWithDelay(startIndex, data.length, functionToRun, timeout); // Lets run it

Try this...

var icount=0;
for (let i in items) {
   icount=icount+1000;
   new beginCount(items[i],icount);
}

function beginCount(item,icount){
  setTimeout(function () {

   new actualFunction(item,icount);

 }, icount);
}

function actualFunction(item,icount){
  //...runs ever 1 second
 console.log(icount);
}

You do it:

_x000D_
_x000D_
console.log('hi')_x000D_
let start = 1_x000D_
setTimeout(function(){_x000D_
  let interval = setInterval(function(){_x000D_
    if(start == 10) clearInterval(interval)_x000D_
    start++_x000D_
    console.log('hello')_x000D_
  }, 3000)_x000D_
}, 3000)
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
_x000D_
_x000D_
_x000D_


Try something like this:

_x000D_
_x000D_
var i = 0, howManyTimes = 10;

function f() {
  console.log("hi");
  i++;
  if (i < howManyTimes) {
    setTimeout(f, 3000);
  }
}

f();
_x000D_
_x000D_
_x000D_


_x000D_
_x000D_
<!DOCTYPE html>_x000D_
<html>_x000D_
<body>_x000D_
_x000D_
<button onclick="myFunction()">Try it</button>_x000D_
_x000D_
<p id="demo"></p>_x000D_
_x000D_
<script>_x000D_
function myFunction() {_x000D_
    for(var i=0; i<5; i++) {_x000D_
     var sno = i+1;_x000D_
        (function myLoop (i) {          _x000D_
             setTimeout(function () {   _x000D_
              alert(i); // Do your function here _x000D_
             }, 1000*i);_x000D_
        })(sno);_x000D_
    }_x000D_
}_x000D_
</script>_x000D_
_x000D_
</body>_x000D_
</html>
_x000D_
_x000D_
_x000D_


var count = 0;

//Parameters:
//  array: []
//  fnc: function (the business logic in form of function-,what you want to execute)
//  delay: milisecond  

function delayLoop(array,fnc,delay){
    if(!array || array.legth == 0)return false;
    setTimeout(function(data){ 
        var data = array[count++];
        fnc && fnc(data);
        //recursion...
        if(count < array.length)
            delayLoop(array,fnc,delay);
        else count = 0;     
    },delay);
}

If using ES6, you could use a for loop to achieve this:

_x000D_
_x000D_
for (let i = 1; i < 10; i++) {
  setTimeout(function timer() {
    console.log("hello world");
  }, i * 3000);
}
_x000D_
_x000D_
_x000D_

It declares i for each iteration, meaning the timeout is what it was before + 1000. This way, what is passed to setTimeout is exactly what we want.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to loops

How to increment a letter N times per iteration and store in an array? Angular 2 Cannot find control with unspecified name attribute on formArrays What is the difference between i = i + 1 and i += 1 in a 'for' loop? Prime numbers between 1 to 100 in C Programming Language Python Loop: List Index Out of Range JavaScript: Difference between .forEach() and .map() Why does using from __future__ import print_function breaks Python2-style print? Creating an array from a text file in Bash Iterate through dictionary values? C# Wait until condition is true

Examples related to sleep

How to make the script wait/sleep in a simple way in unity How do I make a delay in Java? How to create a sleep/delay in nodejs that is Blocking? Javascript sleep/delay/wait function How can I perform a short delay in C# without using sleep? How to add a "sleep" or "wait" to my Lua Script? How to create javascript delay function JavaScript sleep/wait before continuing powershell mouse move does not prevent idle mode What is the proper #include for the function 'sleep()'?