我想在while循环中重复一段文字2秒钟。如何在2秒后打破循环?
这是我到目前为止所尝试过的,但它不起作用:
var repeat = true;
setTimeout(function() { var repeat = false }, 2000)
while(repeat) {
console.log("Let's repeat for 2 seconds...");
}
答案 0 :(得分:3)
JavaScript是单线程的。这意味着只要您的循环运行,您的超时就永远不会被触发。
根据您的需要以及是否要锁定浏览器(通过使用实际的无限循环),您可以使用setInterval
作为循环,并使用setTimeout
来2秒后停止间隔。
console.log("Starting loop");
var interval = setInterval(function () {
console.log("Let's repeat for 2 seconds...");
}, 0);
setTimeout(function() {
clearInterval(interval);
console.log("Finished loop");
}, 2000);

答案 1 :(得分:3)
Additionaly to the other answer you could just check the time instead:
const start = +new Date;
while(+new Date < start + 2000) {
console.log("Let's repeat for 2 seconds...");
}
答案 2 :(得分:0)
如果您完全关心此循环的性能,建议的解决方案将是一个问题。
请注意,在大多数情况下,您不应该在Javascript中进行大量同步迭代,因为这会在这段时间内完全阻塞浏览器或服务器,但是在某些情况下可能需要这样做。请注意,这通常不是一件好事。
下面是我自己的实验,其中有几个选项可以减少检查超时的开销,因为我使用它来基准化其他代码。
我在两个解决方案中都添加了console.time日志,并添加了一些可能值得考虑的优化。
公认的解决方案性能最差:
const label = 'interval';
console.time(label);
let i = 0;
const interval = setInterval(
() => {
i += 1;
},
0);
setTimeout(
() => {
clearInterval(interval);
console.timeEnd(label)
console.log(`${i.toExponential()} iterations`);
},
2000);
// interval: 2001.100ms
// 4.93e+2 iterations
下一个答案的性能要好得多,但是在每次循环运行时,它仍在执行不必要的工作,类型转换和添加操作:
let i = 0;
let start = +new Date;
let label = '+new Date + 2000';
console.time(label);
while ((+new Date) < start + 2000) {
i += 1;
}
console.timeEnd(label)
console.log(`${i.toExponential()} iterations`);
// +new Date + 2000: 1999.800ms
// 1.0921121e+7 iterations
通过使用Date.now()而不是(+ new Date),您可以获得约2.5倍的性能提升:
let label = 'Date.now()';
console.time(label);
let end = Date.now() + 2000;
let i = 0;
while (Date.now() < end) {
i += 1;
}
console.timeEnd(label)
console.log(`${i.toExponential()} iterations`);
// Date.now(): 1999.000ms
// 2.6477108e+7 iterations
如果性能要比停止时精确到十亿分之一秒重要得多,并且操作速度非常快,则可以减少更多操作的检查次数:
let label = 'fuzzy + 2000';
console.time(label);
let end = Date.now() + 2000;
let i = 0;
// Only check the timeout every 1000 operations thanks to lazy evaluation.
while (i % 1000 !== 0 || Date.now() < end) {
i += 1;
}
console.timeEnd(label)
console.log(`${i.toExponential()} iterations`);
// fuzzy + 2000: 1999.800ms
// 6.5632e+8 iterations
好30倍!您需要根据平均循环时间和希望的超时时间调整检查频率。