如何让 Javascript 循环等待现有迭代完成后再开始下一次迭代?
How do I make a Javascript loop wait for existing iteration to finsih before starting the next?
如何让下面的循环等待当前迭代完成后再开始下一次迭代?
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);
我通常使用函数和“.done”在先决条件代码完成后执行代码。我还使用动画中的函数在动画结束后执行代码。
但是我无法理解您如何让代码等待循环迭代完成。如果我将先决条件代码放入一个函数(循环中的所有代码)然后使用 .done,则只剩下循环的右括号放置在“.done”函数中——这显然是行不通的.
谁能解决这个难题?
您可以改为在异步函数中创建 while 循环并使用 await。在下面的代码中,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()
要在您的具体情况下使马蒂亚斯优雅的投票答案栩栩如生:
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++;
}
P.S。如果您想做的是提示用户开球即将开始,但在他们确认警报之前不会开始,那么“警报”没有错。
进一步评论“await 是保留标识符”,封闭函数需要声明为异步。
function playMatch() {
// will fail
await myOtherFunction();
// more code
}
需要:
async function playMatch() {
// will now wait for myOtherFunction to finish before continuing.
await myOtherFunction();
// more code
}
如何让下面的循环等待当前迭代完成后再开始下一次迭代?
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);
我通常使用函数和“.done”在先决条件代码完成后执行代码。我还使用动画中的函数在动画结束后执行代码。
但是我无法理解您如何让代码等待循环迭代完成。如果我将先决条件代码放入一个函数(循环中的所有代码)然后使用 .done,则只剩下循环的右括号放置在“.done”函数中——这显然是行不通的.
谁能解决这个难题?
您可以改为在异步函数中创建 while 循环并使用 await。在下面的代码中,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()
要在您的具体情况下使马蒂亚斯优雅的投票答案栩栩如生:
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++;
}
P.S。如果您想做的是提示用户开球即将开始,但在他们确认警报之前不会开始,那么“警报”没有错。
进一步评论“await 是保留标识符”,封闭函数需要声明为异步。
function playMatch() {
// will fail
await myOtherFunction();
// more code
}
需要:
async function playMatch() {
// will now wait for myOtherFunction to finish before continuing.
await myOtherFunction();
// more code
}