JavaScript线程机制

Posted 简一118

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript线程机制相关的知识,希望对你有一定的参考价值。

  浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:JS引擎线程(用于处理JS)、GUI渲染线程(用于页面渲染)、浏览器事件触发线程(用于控制交互)。

除此之外,有一些执行完就终止的线程,如Http请求线程。

 

1.        javascript引擎线程是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序。

2.        GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

3.        事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

 

  当浏览器在执行JS程序的时候,GUI渲染线程会被保存在一个队列中,直到JS程序执行完成。这样就造成了页面的渲染,就是所说的JS阻塞页面加载问题

  JS引擎是基于事件驱动,采用的是单线程运行机制。即JS引擎会只会顺序的从任务列表中取任务,并执行。

 

很多旁友搞不清楚,既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?

  其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求,当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行 onreadystatechange所设置的函数.

 下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的.虽然每个浏览器内核实现细节不同,但这其中的调用原理都是大同小异。

 

 

 SetTimeout/SetInternal

    其中SetTiemout:在指定的毫秒数后调用指定的代码段;SetInternal:在指定的时间间隔内(ms)循环调用指定的代码段。这两个函数内都涉及到时间计数器,也就是都涉及到一个类似与MFC定时器。JS引擎本身就只能单线程运行,因此定时器需要由其他的外部线程来启动。所以对JS引擎而言,定时器线程可以被视为异步线程。但当定时器时间到达后,所触发的事件则必须在任务列表中排队,等候JS引擎的处理。
     关于setTimeout下面有一个例子,可以帮助深入理解:

        setTimeout(function () { while (true) { } }, 1000);
        setTimeout(function () { alert(\'end 2\'); }, 2000);
        setTimeout(function () { alert(\'end 1\'); }, 100);
        alert(\'end\');

      执行的结果是弹出‘end’‘end 1’,然后浏览器假死,就是不弹出‘end 2’。也就是说第一个settimeout里执行的时候是一个死循环,这个直接导致了理论上比它晚一秒执行的第二个settimeout里的函数被阻塞,这个和我们平时所理解的异步函数多线程互不干扰是不符的。

setTimeout 和 setInterval 在执行异步代码的时候有着根本的不同:
如果一个计时器setTimeout被阻塞而不能立即执行,它将延迟执行直到下一次可能执行的时间点才被执行(比期望的时间间隔要长些)
如果setInterval回调函数的执行时间将足够长(比指定的时间间隔长),它们将连续执行并且彼此之间没有时间间隔

 

引用的网页:

例子:

http://www.cnblogs.com/jeffwongishandsome/archive/2011/06/13/2080145.html

w3c给出的SetTimeout/SetInternal的函数介绍及使用示例

http://www.w3school.com.cn/htmldom/met_win_settimeout.asp

http://www.w3school.com.cn/htmldom/met_win_setinterval.asp

JS的多线程介绍(里面画了一张介绍任务队列机制的原理图,图画的清楚,解释的也很清楚)

http://blog.csdn.net/nx8823520/article/details/7513098

以上是关于JavaScript线程机制的主要内容,如果未能解决你的问题,请参考以下文章

作为前端你了解JavaScript运行机制吗?

JavaScript的执行机制

详解 JavaScript 中的 EventtLoop(事件循环)机制

JavaScript 是单线程的而且是异步的机制

0182 JavaScript执行机制:单线程,同步任务和异步任务,执行栈,消息队列,事件循环

事件循环(Event Loop)机制