Home  >  Q&A  >  body text

How to implement delayed execution in a JavaScript loop?

<p>I want to add a delay/sleep in a <code>while</code> loop: </p> <p>I tried the following: </p> <pre class="brush:php;toolbar:false;">alert('hi'); for(var start = 1; start < 10; start ) { setTimeout(function () { alert('hello'); }, 3000); }</pre> <p>Only the first case is correct: after displaying <code>alert('hi')</code>, it will wait for 3 seconds and then display <code>alert('hello' )</code>, but then <code>alert('hello')</code> will be displayed repeatedly. </p> <p>What I want is that after 3 seconds of showing <code>alert('hello')</code>, it needs to wait another 3 seconds before showing <code>alert(' hello')</code>, and so on. </p>
P粉680000555P粉680000555426 days ago455

reply all(2)I'll reply

  • P粉718165540

    P粉7181655402023-08-21 11:04:40

    Since ES7, there is a better way to waitloop:

    // 返回一个在“ms”毫秒后解析的Promise
    const timer = ms => new Promise(res => setTimeout(res, ms))
    
    async function load () { // 我们需要将循环包装在一个异步函数中才能使其工作
      for (var i = 0; i < 3; i++) {
        console.log(i);
        await timer(3000); // 然后可以等待创建的Promise
      }
    }
    
    load();

    When the engine reaches the await section, it sets a timeout and pauses execution of the async function . Then, when the timeout completes, execution continues at that point. This is very useful because you can defer (1) nested loops, (2) conditionals, (3) nested functions:

    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)); }

    Reference materials on MDN

    Although ES7 is now supported by NodeJS and modern browsers, you may want to transpile it with BabelJS to run everywhere.

    reply
    0
  • P粉659518294

    P粉6595182942023-08-21 10:19:20

    setTimeout() The function is non-blocking and returns immediately. So your loop iterates very quickly and triggers the 3 second timeout in quick succession. That's why your first alert pops up after 3 seconds and all other alerts follow continuously without any delay.

    You may want to use code similar to:

    var i = 1;                  //  将计数器设置为1
    
    function myLoop() {         //  创建一个循环函数
      setTimeout(function() {   //  当调用循环时,调用一个3秒的setTimeout
        console.log('hello');   //  在这里写入您的代码
        i++;                    //  增加计数器
        if (i < 10) {           //  如果计数器小于10,则调用循环函数
          myLoop();             //  ..  再次触发另一个setTimeout()
        }                       //  ..  
      }, 3000)
    }
    
    myLoop();                   //  启动循环

    reply
    0
  • Cancelreply