2017-04-20 43 views
1

我希望我的标题是正确的。我今天在接受采访时被一个涉及事件循环/单线程的问题困住了。这里是代码:单线程块如何在JavaScript中对DOM进行操作?

function longCB(){ 
    for (var i = 0; i <= 9999; i++){ 
    console.log(i); 
    } 
    $('#status').text('hello') 
} 

$('#status').text('hi') 
longCB(); 

问题是为什么DOM从不在#status div上显示“hi”? 面试官解释说,这是因为JavaScript中的单线程,并解释说,即使将longCB()设置为0,setTimeout也会使其工作。在审查事件循环/事件调用和调用堆栈之后,我仍然完全难以理解,为什么这不起作用?不应该行

$('#status').text('hi') 

甚至在调用longCB()之前完成?我错过了什么?先进的谢谢你。

回答

1

这是因为单线程也由浏览器的渲染引擎共享。只要JS同步运行,屏幕上的页面就不会更新。为什么?好了,说你有这个代码:

elem.style.color = 'red'; 
elem.style.opacity = '1'; 
elem.textContent = 'Hello'; 

你不会想要的元素,以显示红色的旧文本,然后使它更加不透明,然后将文本更改为你好。你只希望文本立即改变,变得红色和不透明。这是为什么只有在所有JS运行之后才进行渲染的一个原因。另一个原因与性能有关。渲染需要时间!

$('#status').text('hi') 
longCB(); 

你没有错,当你说该文本甚至称longCB()之前设置为“喜”,但因为线程仍在运行JS,页面不会得到重绘,只是还没有。使用setTimeout只是将方法调用添加到将来某个时间点的一堆事物中,并且保证浏览器在同步脚本的末尾和处理事件或超时之间进行渲染。

+0

非常感谢你。对此,我真的非常感激。我会更多地研究它,但是你能否解释一下线程究竟是什么?每个单独的线程是否是一个块范围? – user1842315

+1

我刚刚观看了Philip Roberts关于事件循环的主题演讲。 https://www.youtube.com/watch?v=8aGhZQkoFbQ我意识到现在有一​​个渲染队列只能在调用堆栈清除时运行。由于longCB()在调用堆栈上,因此浏览器不会使用文本“hi”呈现#status。非常感谢 – user1842315

+0

程序设计语言中的线程或进程通常意味着在代码中移动的单个“游标”,而不是同时运行的多段代码。不要混淆,线程也可以指OS内存和处理器时间管理的块。例如,对于每个选项卡,Chrome都有不同的处理过程,可以在任务管理器中看到。虽然处理器可以有多个有时称为线程的核心。这是一个非常松散的术语来思考它。 –

相关问题