我仍然认为javascript是单线程的。但是当我想到事件处理机制时,我有些疑惑。
为什么我认为这样即使在从队列处理一个事件时,它也可以监听或者可以将事件推送到同一个队列。 我创建了一个例子如下:
<html>
<head>
<script>
function clicked(){
alert("clicked in between..");
}
function longRun(){
for(var i=0;i<50000;i++){
console.log(i);
}
alert("completed .... ");
}
</script>
</head>
<body>
<input type="button" value="quick!" onclick="clicked();"/>
<input type="button" value="long run!" onclick="longRun();"/>
</body>
</html>
&#13;
当我点击长跑!时,需要一些时间才能完成,但与此同时,如果我点击快速!,它会被添加到事件队列中并且将在长期活动后立即执行。
实际发生了什么?任何人都可以解释/纠正我
答案 0 :(得分:4)
除了webWorkers(我们在这里没有讨论),浏览器中每个窗口只有一个“用户线程”。这意味着只有一个线程运行您的用户Javascript。
这并不意味着封面下的浏览器引擎没有其他一些线程来处理非Javascript处理。事实上,这很可能就是这种情况。但是,由于这些其他可能的线程,从未实际运行任何Javascript或影响任何Javascript变量,它们不会直接影响JS执行环境。
是的,这些其他线程可能确实会将事物插入到JS事件队列中,以后在主JS线程准备好处理下一个事件时将会被拾取。
有关详细信息和相关文章列表,请参阅此答案How does JavaScript handle AJAX responses in the background?。
答案 1 :(得分:2)
每个标签只有一个主题。该线程执行JavaScript执行和屏幕更新。当longRun
正在执行时,您无法对按钮上的点击做出反应;所有50000次迭代完成后,您注册的事件将被触发。
澄清:事件被放入队列。队列正由标签线程按顺序执行。
编辑:事实上,那些工作人员,但他们表现得好像他们在不同的标签中执行 - 他们有自己的上下文,并且只能使用postMessage
与调用程序通信。
答案 2 :(得分:0)
如果你使用safari,每个浏览器都会使用堆栈,所以你会在inspect元素中看到操作被放入堆栈中,所以根据你的脚本代码,它首先完成5000次循环的循环。
答案 3 :(得分:-1)
Javascript适用于单线程.Event排队并以 fifo 顺序处理。
我们正在做的是编写事件处理程序,它只是一个从队列处理事件后将执行的回调函数,因此它的单线程但本质上是异步的。
您可以从http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/
了解有关此内容的更多信息