1

This is an example:

function func1()
{
   setTimeout(function(){doSomething();}, 3000);
}
for(i=0;i<10;i++)
{
   func1();
}

after executing it , the delay happens only in the first loop, but it didn't happen in the rest of the loops in that 'for' expression.

I want to make the delay happen in all of the loop and not only in the first time.
What's wrong in my code ?

Filburt
  • 17,626
  • 12
  • 64
  • 115
R00t_R3z
  • 98
  • 1
  • 13
  • 1
    The should all happen, but at the same time. – elclanrs Jul 09 '15 at 06:28
  • 1
    All of the `doSomething`s are scheduled to execute 3 seconds from when they are scheduled. Since they are scheduled right after one another with barely any time between them, they will execute 3 seconds after that, with barely any time between them. What did you expect to happen? If you wanted them to execute with 3 seconds between each of them, schedule them at 3000, 6000, 9000... or schedule the next one at the end of the current one, not in a loop outside of them. – Amadan Jul 09 '15 at 06:30
  • why don't you increment a counter and spit it out in your doSomething function to see howmany times it gets fired? (not sure if timestamp will help as they all could print the same timestamp) – Alp Jul 09 '15 at 06:34
  • @Amadan NOW i understand, that the miliseconds are from the time of Executing the page and not from reading that specific line from the browser, it was a misunderstanding, Thanks – R00t_R3z Jul 09 '15 at 06:38
  • No, it is from executing `setTimeout`. But all of the `setTimeout` calls are executed in a loop, without delay between them. – Amadan Jul 09 '15 at 06:40
  • 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 Jan 23 '22 at 17:39

7 Answers7

7

You are scheduling 10 calls, but the problem is all are getting scheduled for the same time, ie after 3 seconds.

If you want to call them incrementally then you need to increase the delay in each call.

A solution will be is to pass a delay unit value to the func1 like

function func1(i) {
  setTimeout(function() {
    doSomething();
  }, i * 500);//reduced delay for testing
}
for (i = 0; i < 10; i++) {
  func1(i + 1);
}

var counter = 0;

function doSomething() {
  snippet.log('called: ' + ++counter)
}
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<!-- To show result in the dom instead of console, only to be used in the snippet not in production -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
4

The loop will schedule 10 timeouts all to be completed after 3 seconds. You can use recursion with setTimeout:

function loopAsync(delay, n, f) {
  setTimeout(function() {
    if (n > 0) {
      f()
      loopAsync(delay, n - 1, f)
    }
  }, delay)
}

loopAsync(3000, 10, doSomething)
elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • Very nice. Much simpler than some of these: http://stackoverflow.com/questions/4288759/asynchronous-for-cycle-in-javascript – mplungjan Jul 09 '15 at 06:41
2

What is heppening is that you are calling 10 times (without delay) func1() then what you have is 10 functions all on the same time, the solution is simple, use setInterval, here is a fiddle

Agamennon
  • 186
  • 7
  • Works, thanks. You should copy your code to here so that if JSFiddle ceases to be then at least we have the cold hard code. – HankCa Oct 19 '17 at 04:04
1

With async.js:

async.timesSeries(5, function (n, next) {
    setTimeout(function(){
        doSomething();
        next();
    }, 3000);
});
Exos
  • 3,958
  • 2
  • 22
  • 30
1

If you want iterate with constant delay, IMHO you better use setInterval:

var loops = 9,
    intervalId = setInterval(function () {
        // My super code goes here
        console.log(loops);
        loops-- <= 0 && (clearInterval(intervalId));
    }, 3000);

I've made a jsfiddle for you.

Alexander Arutinyants
  • 1,619
  • 2
  • 23
  • 49
0

The for loop is running continuously so each call is 3000 millisecond of that call. Resulting in no delay between two calls. For better understanding, loop call func1 at time t and t + 1. So it will execute at t + 3000 and T + 3001 leaving no difference.

You can try below approach :-

function func1(i){
     setTimeout(function(){doSomething();}, i * 3000);
 }
for(i=i;i<=10;i++){
  func1(i);
}

Note:- Loop intialized with i = 1.

Panther
  • 3,312
  • 9
  • 27
  • 50
0

It is because setTimeout() function is non-blocking. Therefore your setTimeout() function is running only first time.

Try this code...

var i = 1;
    function func1(){
        setTimeout(function(){
            doSomething();
            i++;
            if(i < 10){
                func1();
            }
        }, 3000);
    }
func1();