setTimeout() method inside a while loop

I have read the relevant pages on w3schools and other similar questions here but cannot seem to understand what's wrong about the following bit :

var myfunc03 = function (i) {
  document.getElementById('d01').innerHTML += 100-i+"<br>";
};

var myFunc01 = function() {
  i=0;
  while (i<100) {
    setTimeout(myfunc03(i), 1000)
    i++;
  }
};

when myFunc01(); is run.

There's no pause whatsoever and all possible values for i is listed at once.

Is there a logical mistake here?

The while loop will not wait for setTimeout() to complete. You need to set different time delay for each to execute them with different times and use closure for holding the value of i. Also in your case, function will be executed initially and return value is setting as argument in setTimeout(), so either you need to call the function inside an anonymous function or set the function directly.

var myFunc01 = function() {
  var i = 0;
  while (i < 100) {
    (function(i) {
      setTimeout(function() {
        document.getElementById('d01').innerHTML += 100 - i + "<br>";
      }, 1000 * i)
    })(i++)
  }
};

myFunc01();
<span id="d01"></span>

The setTimeout() method calls a function or evaluates an expression after a specified number of milliseconds. Tip: 1000 ms = 1 second. Tip: The function is only executed once. If you need to repeat execution, use the setInterval() method. Tip: Use the clearTimeout() method to prevent the function from running.

You can do it more simply with recursion:

var i = 0;
function f1() { ... };   
function f() {
    f1();
    i += 1;
    setTimeout(function() {
        if(i < 100) {
            f();
        }
    }, 1000);
}
f();
Example

var i = 0;

var myfunc03 = function(i) {
  document.getElementById('d01').innerHTML += 100 - i + "<br>";
};

var myFunc01 = function() {
  myfunc03(i);
  i += 1;
  setTimeout(function() {
    if (i < 100) {
      myFunc01();
    }
  }, 1000);
}

myFunc01();
<div id="d01"></div>

A while loop blocks the whole page until it ends, and as your loop never exits its infinite. You may replace it with a high speed interval: const loop = setInterval(function(){ if(battleOver) return clearInterval(loop);

Yes. There are 2 problems in your code:

  1. The setTimeout function accept a function as the first argument, but in your code, myfunc03(i) returns nothing
  2. The while loop won't meet you needs, instead, you have to use recursive function. Since the second function should be invoked after the first timeout is fired.

Sample code:

var myfunc03 = function (i) {
  setTimeout(function() {
    document.getElementById('d01').innerHTML += 100-i+"<br>";
    if (i < 100) {
      i++;
      myfunc03(i);
    }
  }, 1000);
};

var myFunc01 = function() {
  myfunc03(0);
};

myFunc01();
<div id="d01"></div>

setTimeout inside for loop [duplicate] Ask Question Asked 10 years, 7 months ago. whereas the loop method will fire the callback every delay ms.

setTimeout allows us to run a function once after the interval of time. setInterval allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval. These methods are not a part of JavaScript specification. But most environments have the internal scheduler and provide these methods.

while waiting for setTimeout :

(async () => {
  var i = 0;
  while (await new Promise(resolve => setTimeout(() => resolve(i++), 1000)) < 100) {
    console.log("I get printed 100 times every second");
  }
})();

The problem with setInterval() and setTimeout() is that there is no guarantee your code will run in the specified time. By using setTimeout() and calling it recursively, you're ensuring that all previous operations inside the timeout are complete before the next iteration of the code begins.

public run() { let i = 0; while (i < 4) { setTimeout(this.timer,3000); i++; } } public timer(){ console.log("done") } However this seems to wait for 3 seconds, or browser is just slow and then it prints 4 times done.

The problem is, that my while loop runs too fast and the script sends too many requests per second to the google API. Therefore I would like to build a sleep function which delays the request. Thus I could also use this function to delay other requests. If there is another way to delay the request, please let me know.

JavaScript doesn’t offer any wait command to add a delay to the loops but we can do so using setTimeout method. This method executes a function, after waiting a specified number of milliseconds. This method executes a function, after waiting a specified number of milliseconds.

Comments
  • That of course highlights his second mistake -- accessing a modified variable (i) from within a closure. When the timeout fires, i will have changed to whatever the last one is.
  • setTimeout expects a Function as the first parameter but you're passing the result of myfunc03 (which is underfined because you're invoking it)
  • Thorough explanation. I was running into the same issue. Great examples, thanks!
  • For modern browsers, this is the best solution, because it avoids the awkwardness of closures. However, the second parameter should be 1000 * i; otherwise, you're setting 100 timeouts at the same time to 1s. Compare jsfiddle.net/ofpp26or/2 to jsfiddle.net/ofpp26or
  • Yea, that's correct. I intended to only show syntax-wise, as that might have caused js-errors. He might use time-parameters as per his logic requirements.
  • Please work on your answers. this is not readable nor understandable
  • @mplungjan yeah my bad!
  • You did not address the closure issue
  • I know, others already did that and originally I had missed it. So I just modified my original answer. Didn't feel right to copy off someone else's answer :)
  • @mplungjan it's okay. I don't write stuff just for votes or reputation. Just killing some free time and helping fellow coders out :) Anyways corrected the answer as you insisted