在2个seonds之后留下一个循环

时间:2018-03-22 22:56:16

标签: javascript

我想在while循环中重复一段文字2秒钟。如何在2秒后打破循环?

这是我到目前为止所尝试过的,但它不起作用:

var repeat = true;
setTimeout(function() { var repeat = false }, 2000)
while(repeat) {
    console.log("Let's repeat for 2 seconds...");
}

3 个答案:

答案 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倍!您需要根据平均循环时间和希望的超时时间调整检查频率。