我想知道在Chrome的控制台中,JavaScript的while
语句可以在一毫秒内增加一个变量多少次,所以我直接将以下代码片段快速地写入了控制台:
var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }
问题在于它一直运行。
这是为什么,我该如何解决?
我想知道在Chrome的控制台中,JavaScript的while
语句可以在一毫秒内增加一个变量多少次,所以我直接将以下代码片段快速地写入了控制台:
var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }
问题在于它一直运行。
这是为什么,我该如何解决?
run=false
的函数。该函数被安排在当前函数(或其他当前活动内容)运行后运行。setTimeout()
回调函数,并将run=false
。setTimeout()
方法在这里行不通。您可能通过在while
条件中检查时间来解决此问题,但这会破坏实际测量。
1至少对于更实际的目的,您可以将其视为单线程。实际上有一个所谓的“事件循环”。在该循环中,所有函数都排队等待执行。如果您排队了新的函数,则它将放置在该队列中的相应位置。在当前函数完成后,引擎从队列中获取下一个函数(根据由setTimeout()
引入的时间),并执行它。
因此,在任何时候只有一个函数在执行,从而使执行非常单线程。有一些关于事件的例外情况,在下面的链接中进行讨论。
供参考:
https://dev59.com/qHLYa4cB1Zd3GeqPZI7V#16757582
在此处详细解释了类似的情境。
https://dev59.com/BHE85IYBdhLWcg3whT9r#2734311
更深入地描述了何时可以将JS视为单线程,何时不行。
var start = (new Date()).getTime();
。然后在while
语句中,从当前时间减去该时间,检查得到的数字是否小于你期望的延迟时间。while ((new Date()).getTime() - start < delay)
。 - Useless CodeJavaScript是单线程的,因此在循环过程中,其他任何东西都不会被执行。
为了保持 Chrome 的真实速度,而不必经常重新获取时间来计算速度,您可以尝试使用以下 JS 代码:
var start = new Date().getTime()
var i = 0
while(i<1000000)
{
i++
}
var end = new Date().getTime()
var delta = end-start
var speed = i/delta
console.log(speed + " loops per millisecond")
Javascript是单线程的,这意味着它一次只能运行一个指令,按顺序执行。
事件系统,就像许多其他语言和库一样,由事件循环处理。事件循环基本上是一个循环,在每个迭代中检查队列中的消息,并分发事件。
在Javascript中(与实现此模式的大多数语言一样),当堆栈为空时,事件循环被调用,也就是说,当所有函数都返回时,在程序代码的末尾。
幕后,您的“真正”的程序看起来像这样:
var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }
while(true) {
/*
* check for new messages in the queue and dispatch
* events if there are some
*/
processEvents();
}
因此,来自时钟的超时消息从未被处理。
关于事件循环的更多信息请参见: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop
当然,它有点更加复杂,请查看这些示例:Is JavaScript guaranteed to be single-threaded?(tl;dr:在某些浏览器引擎中,一些外部事件不依赖于事件循环,并在发生时立即触发,抢占当前任务。但是,setTimeout并不会立即触发,而只是将消息添加到队列中而已。)
var run = true, i = 0; function loop() { i++; if (run) setTimeout(loop, 0); }; setTimeout(function() { run = false }, 1); loop();
- Izkata