我想知道一个JavaScriptwhile
语句(在Chrome的控制台中)可以在一毫秒内递增一次变量的次数,因此我迅速将此代码段直接写入控制台:
var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }
问题是它永远运行。
为什么会发生这种情况,我该如何解决?
我想知道一个JavaScriptwhile
语句(在Chrome的控制台中)可以在一毫秒内递增一次变量的次数,因此我迅速将此代码段直接写入控制台:
var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }
问题是它永远运行。
为什么会发生这种情况,我该如何解决?
var run = true, i = 0; function loop() { i++; if (run) setTimeout(loop, 0); }; setTimeout(function() { run = false }, 1); loop();
Answers:
这回到了JavaScript 1的单线程性质。发生的事情几乎是这样的:
run = false
。这是计划运行后,目前的功能是运行(或任何其他当前处于活动状态)。setTimeout()
将执行和run=false
。如您所见,一种setTimeout()
方法在这里行不通。您可以通过检查while
条件中的时间来解决此问题,但这会干扰您的实际测量。
1至少出于更实际的目的,您可以将其视为单线程。实际上,存在一个所谓的“事件循环”。在该循环中,所有函数将排队等待执行。如果将新功能排队,则将其放在该队列内的相应位置。后的当前功能完成时,引擎将在下一个函数从队列(相对于定时作为引入,例如,通过setTimeout()
并执行它。
如在每个时间点的结果只有一个功能被执行,从而使执行漂亮很多单线程事件都有一些例外,下面的链接中对此进行了讨论。
以供参考:
https://stackoverflow.com/a/16757582/1169798
在此,对类似情况进行了更详细的说明
https://stackoverflow.com/a/2734311/1169798
关于何时可以将JS视为单线程以及何时不视为JS的更深入的描述。
var start = (new Date()).getTime();
然后在while
语句中从当前时间中减去该时间,并检查结果数是否小于预期的延迟。while ((new Date()).getTime() - start < delay)
。
JavaScript是单线程的,因此,当您处于循环中时,不会执行任何其他操作。
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
当然,它有点复杂,请在此处查看以下示例:是否保证JavaScript是单线程的?(tl; dr:在某些浏览器引擎中,某些外部事件不依赖于事件循环,而是在事件发生时立即触发,从而抢占了当前任务。但是setTimeout并非如此,它们只是向队列中添加一条消息而且永远不会立即射击。)