[英]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.在先决条件代码完成后,我通常使用函数和“.done”来执行代码。 I have also used functions within animations to execute code after the animation has finished.在 animation 完成后,我还使用动画中的函数来执行代码。
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.如果我将先决条件代码放入 function(循环中的所有代码)然后 use.done,则只有循环的右括号可以放在“.done” function 中 - 这显然不起作用.
Can anyone solve this conundrum?谁能解决这个难题?
You can make a while loop in an async function instead and use await.您可以在异步 function 中创建一个 while 循环,然后使用 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.在下面的代码中,while 循环在每次迭代时至少等待 2 秒,但最多与任务所需的时间一样长。
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()
To bring Matthias's elegant up-voted answer to life in your specific situation:在您的特定情况下,将 Matthias 优雅的投票答案带入生活:
var minute = 0
// reusable function to wait the specified amount of time (1000ms in your case)
const sleep = time => new Promise(resolve => setTimeout(resolve, time))
alert ("Kick Off");
while (minute < 91)
{
const processThisMinuteTask = new Promise((res, rej) => {
// lots of code with Ajax calls
// can take from a fraction of a second to 30 seconds to run code
// depending on conditions
// NOTE: use AWAIT for all Ajax calls
res();
});
// will wait for both:
// a) your processThisMinuteTask to finsih
// b) 1000ms to pass
// So, will mean that this iteration will wait for whichever of those is longest
await Promise.all([processThisMinuteTask, sleep(1000)]);
minute++;
}
PS Nothing wrong with the "Alert" if what you want to do is prompt the user that kick-off is about to start, but will not start until they acknowledge the alert. PS 如果您想要做的是提示用户开球即将开始,但在他们确认警报之前不会开始,那么“警报”没有任何问题。
Further to comment about "await is a reserved identifier", the enclosing function needs to be declared as async.进一步评论“等待是一个保留的标识符”,封闭的 function 需要声明为异步。
function playMatch() {
// will fail
await myOtherFunction();
// more code
}
Needs to be:需要是:
async function playMatch() {
// will now wait for myOtherFunction to finish before continuing.
await myOtherFunction();
// more code
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.