23

I am working on a website, where I need to create a pause or delay.
So please tell me How to create pause or delay in for loop in javascript or jQuery

This is a test example

 var s = document.getElementById("div1");
 for (i = 0; i < 10; i++) {
     s.innerHTML = s.innerHTML + i.toString();
     //create a pause of 2 seconds.
  }
Amit
  • 21,570
  • 27
  • 74
  • 94
  • You cannot "pause" JavaScript in a web browser. You can, however, setup timers and cause code to be executed at a later point with the `setTimeout()` and `setInterval()` APIs available in all browsers. – Pointy Apr 07 '12 at 22:06
  • tldr: You have to convert the code to recursive, continuation passing style if you want to take advantage of asynchonicity. (Well, that or use a clever trick like Guffa did) – hugomg Apr 08 '12 at 00:25
  • Similar to http://stackoverflow.com/questions/4548034/create-a-pause-inside-a-while-loop-in-javascript – Paul Verest Mar 06 '14 at 07:45
  • Does this answer your question? [How do I add a delay in a JavaScript loop?](https://stackoverflow.com/questions/3583724/how-do-i-add-a-delay-in-a-javascript-loop) – Ivar Apr 13 '21 at 09:30

14 Answers14

29

You can't use a delay in the function, because then the change that you do to the element would not show up until you exit the function.

Use the setTimeout to run pieces of code at a later time:

var s = document.getElementById("div1");
for (i = 0; i < 10; i++) {

  // create a closure to preserve the value of "i"
  (function(i){

    window.setTimeout(function(){
      s.innerHTML = s.innerHTML + i.toString();
    }, i * 2000);

  }(i));

}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 1
    @Pointy: Good point. I added a closure to preserve each value. – Guffa Apr 07 '12 at 22:11
  • @Guffa: Your brackets are off in your function execution – BrokenGlass Apr 07 '12 at 23:55
  • @BrokenGlass: No, they are not. The code runs just fine. http://jsfiddle.net/Guffa/PcuxY/ – Guffa Apr 08 '12 at 08:27
  • I'm a bit confused, if the closure "preserves the value of `i`" why isn't what's calculated by `i * 2000` equal to `0` as `0` is the first value of `i`? Or, if `i` is being incremented on each iteration, why is the duration between each `innerHTML` update not increased likewise? – 1252748 Nov 23 '16 at 06:03
  • it is even more confusing when I log at the first line of the loop and the first line of the iife: they both log` 0-9` immediately. i know it has been a long time, but can you explain a bit what is going on here? http://jsbin.com/foqineciva/edit?html,js,output – 1252748 Nov 23 '16 at 06:15
8
var wonderfulFunction = function(i) {
   var s = document.getElementById("div1"); //you could pass this element as a parameter as well
   i = i || 0;
   if(i < 10) {
      s.innerHTML = s.innerHTML + i.toString();

      i++;
      //create a pause of 2 seconds.
      setTimeout(function() { wonderfulFunction(i) }, 2000);          
   }
}

//first call
wonderfulFunction(); //or wonderfulFunction(0);

You can't pause javascript code, the whole language is made to work with events, the solution I provided let's you execute the function with some delay, but the execution never stops.

nicosantangelo
  • 13,216
  • 3
  • 33
  • 47
  • 2
    This will have a big problem because all the timeout funtions share the same "i" value. They'll all pass 11 to "wonderfulFunction". – Pointy Apr 07 '12 at 22:10
  • What's the `for` loop for? Given it always executes the `break` wouldn't it be more straightforward to use an `if` statement? For the same reason, I don't see why you need the inner function... – nnnnnn Apr 07 '12 at 22:34
  • @nnnnnn Because I edited the answer without thinking. I took a different approach at first an then I changed it to use the clousure. The way is written the `for` is useless, edit time :). – nicosantangelo Apr 07 '12 at 22:39
  • I'm sorry, my JS syntax isn't the best. What does the line `i = i || 0;` mean? – Victor Resnov Nov 28 '19 at 15:07
  • @VictorResnov it means "assign `i` to itself if the value of `i` is truthy, otherwise assign it to 0" https://developer.mozilla.org/en-US/docs/Glossary/Truthy – nicosantangelo Mar 05 '20 at 15:26
3

I tried all one, but I think this code is better one, it is very simple code.

var s = document.getElementById("div1");
var i = 0;
setInterval(function () {s.innerHTML = s.innerHTML + i.toString();  i++;}, 2000);
Amit
  • 21,570
  • 27
  • 74
  • 94
2

if you want to create pause or delay in FOR loop,the only real method is

while (true) {
    if( new Date()-startTime >= 2000) {
        break;
    }
}

the startTime is the time before you run the while but this method will cause the browsers become very slow

tangqiaoboy
  • 1,476
  • 1
  • 15
  • 32
SKing7
  • 2,204
  • 4
  • 21
  • 29
0

It is impossible to directly pause a Javascript function within a for loop then later resume at that point.

Elliot Bonneville
  • 51,872
  • 23
  • 96
  • 123
0

This is how you should do it

var i = 0;
setTimeout(function() {
   s.innerHTML = s.innerHTML + i.toString();
   i++;
},2000);
Starx
  • 77,474
  • 47
  • 185
  • 261
0

The following code is an example of pseudo-multithreading that you can do in JS, it's roughly an example of how you can delay each iteration of a loop:

var counter = 0;

// A single iteration of your loop
// log the current value of counter as an example
// then wait before doing the next iteration
function printCounter() {
    console.log(counter);
    counter++;
    if (counter < 10)
        setTimeout(printCounter, 1000);
}

// Start the loop    
printCounter();
zatatatata
  • 4,761
  • 1
  • 20
  • 41
0

While several of the other answers would work, I find the code to be less elegant. The Frame.js library was designed to solve this problem exactly. Using Frame you could do it like this:

var s = document.getElementById("div1");
for (i = 0; i < 10; i++) {
   Frame(2000, function(callback){ // each iteration would pause by 2 secs
      s.innerHTML = s.innerHTML + i.toString();
      callback();
   }); 
}
Frame.start();

In this case, it is nearly the same as the examples that use setTimeout, but Frame offers a lot of advantages, especially if the you are trying to do multiple or nested timeouts, or have a larger JS application that the timeouts need to work within.

BishopZ
  • 6,269
  • 8
  • 45
  • 58
0

I am executing a function where I need access to the outside object properties. So, the closure in Guffa solution doesn't work for me. I found a variation of nicosantangelo solution by simply wrapping the setTimeout in an if statement so it doesn't run forever.

    var i = 0;
    function test(){

        rootObj.arrayOfObj[i].someFunction();
        i++;
        if( i < rootObj.arrayOfObj.length ){
            setTimeout(test, 50 ); //50ms delay
        }

    }
    test();
Community
  • 1
  • 1
Sean Novak
  • 510
  • 2
  • 14
0

The way I found was to simply use setInterval() to loop instead. Here's my code example :

var i = 0;
var inte = setInterval(() => {
    doSomething();

    if (i == 9) clearInterval(inte);
    i++;
}, 1000);

function doSomething() {
    console.log(i);
};

This loops from 0 to 9 waiting 1 second in between each iteration.

Output :

0 1 2 3 4 5 6 7 8 9
BaSsGaz
  • 666
  • 1
  • 18
  • 31
0

It is not possible to pause a loop. However you can delay the execution of code fragments with the setTimeout() function. It would not make a lot of sense to pause the entire execution anyway.

Ben Bieler
  • 1,518
  • 1
  • 14
  • 22
  • 3
    "It would not make a lot of sense to pause the entire execution anyway" - Says who? It might not be common, but there are legitimate reasons why you might want to do this. – Kevin Robinson Apr 05 '21 at 17:01
0

I am using while loop and check the pause variable to check the user pause/resume the code.

var pause = false;
(async () => {
  for (let index = 0; index < 1000; index++) {
    while (pause) {
      await new Promise((res) => setTimeout(res, 1000));
      console.log("waiting");
    }
    await new Promise((res) => setTimeout(res, 1000));
    console.log(index);
  }
})();

const pausefunc = async () => {
  pause = true;
};
const playfunc = () => {
  pause = false;
};
    <button onclick="playfunc()">Play</button>
    <button onclick="pausefunc()">Pause</button>
Atul
  • 36
  • 1
0

You can pause within loops using async and await. Here is an example. Carry out your actions in the area above the await line (console log in the example)

async function yay() {
  for (let i = 0; i < 5; i++) {
    // actions here
    console.log(i);

    await new Promise(resolve => setTimeout(resolve, 1000));
  }
};

yay();
-1

I used a do...while loop to put a delay in my code for a modal dialog that was closing too quickly.

your stuff....

var tNow = Date.now();
var dateDiff = 0;
do {
    dateDiff = Date.now() - tNow;
} while (dateDiff < 1000); //milliseconds - 2000 = 2 seconds

your stuff....
Jon649
  • 279
  • 3
  • 7