Search code examples
javascriptjqueryloopsasynchronouswait

How do I make a Javascript loop wait for existing iteration to finsih before starting the next?


How do I make the below loop wait for current iteration to finish before it starts the next iteration?

var minute = 0

alert ("Kick Off");

var refreshIntervalId = setInterval(function() {     
  if (minute < 91) {
    // lots of code with Ajax calls
    // can take from a fraction of a second to 30 seconds to run code
    // depending on conditions
  } else {
    clearInterval(refreshIntervalId);
  } 
  minute++         
}, 1000);

I usually use functions and '.done' to execute code after pre-requisite code has finished. I have also used functions within animations to execute code after the animation has finished.

However I can't get my head around how you make the code to wait for an iteration of a loop to finish. If I put the pre-requisite code into a function (all the code within the loop) and then use .done, there is only the closing brackets of the loop left to put within a '.done' function - which obviously will not work.

Can anyone solve this conundrum?


Solution

  • You can make a while loop in an async function instead and use await. In the code below, the while-loop waits at least 2 seconds at each iteration but at most as long as the task takes.

    const sleep = time => new Promise(resolve => setTimeout(resolve, time))  
    
    async function main() {
      while (true) {
        console.log("new iteration")
        const task = new Promise((resolve, reject) => {
          // things that take long go here…
          const duration = Math.random()*4000
          setTimeout(() => {
            console.log(`done, task took ${Math.round(duration)}ms`)
            resolve()
          }, duration)
        })
        // wait until task is finished but at least 2 seconds
        await Promise.all([task, sleep(2000)])
      }
    }
    
    main()