2017-06-03 60 views
1
setInterval(function(){console.log("hello")},2000); 
while(true){} 

“hello”永远不会被打印。 我认为事件循环运行在不同的线程中,但在这里看起来像'while循环'阻止了'事件循环'的执行。 有人可以对此有所了解吗?

我对js非常天真,所以如果问题太单调太对不起。js while(true){} blocks event loop

+7

JS是单线程的。 –

+0

我意识到我是一个业余爱好者,但我一直在使用和编写JavaScript一段时间,而我从来没有见过使用'while(true)'的理由,while(variableName){if(东西){variableName = false; }'有它的用途,但不是一个不可避免的无限循环,据我所知... –

+0

@DavidThomas'while(true)'肯定有它的用处:当你没有明确的条件变量,当你需要重复,直到发生/完成/等。一个简单的例子:https://pastebin.com/qEeuUxAs – zerkms

回答

5

你必须明白

如何浏览器内部做的setTimeout?

我会简单介绍一下。

要了解更多关于这个

这里是jsconf2014

Philip Roberts: What the heck is the event loop anyway?

也由菲利普·罗伯茨 事件循环更detail explanation,看到这个过程中的行动是有伟大的工具看看 在loupe

要了解您必须了解JavaScript中的事件队列。浏览器中实现了事件队列。每当一个事件在js中被触发,所有这些事件(比如点击等等)都被添加到这个队列中。当您的浏览器无法执行时,它会从队列中取出一个事件并逐个执行它们。

现在,当您拨打setTimeoutsetInterval时,您的回调将被注册到浏览器中的计时器,并在给定时间过期后被添加到事件队列中,并最终由JavaScript从队列中取出事件并执行它。

发生这种情况,因为JavaScript执行是单线程,他们一次只能执行一件事。所以,他们不能执行其他的JavaScript并跟踪你的计时器。这就是为什么这些定时器在浏览器中注册(浏览器不是单线程),它可以跟踪定时器并在定时器到期后在队列中添加一个事件。

只有在这种情况下,该事件才会在指定的时间间隔内一次又一次地添加到队列中,直到它被清除或刷新浏览器页面为止,才会发生setInterval

注意

传递给这些函数的延迟参数是最小延迟时间 执行回调。这是因为在定时器到期之后,浏览器将该事件添加到队列中以由 javascript引擎执行,但执行回调取决于队列中的事件位置,并且由于引擎是单线程的,因此 将执行队列中的所有事件一个接一个。

因此,当您的其他代码阻塞线程并且没有时间处理队列中的内容时,您的回调可能需要超过指定的延迟时间。

正如我所说的JavaScript是单线程。所以,如果你长时间阻塞线程。

这样的代码

while(true) { //infinite loop 
} 

您的用户可以得到一个消息,说页面不响应

而在这里,您的setTimeout事件将永远不会执行。

+0

“有一个事件队列“---实际上有多个任务队列。因此,根据任务将其添加到相应的队列中。 – zerkms

+0

是的,有但我不会详细只是给出一个想法 –

+0

“不详细”:D –