本文主要是介绍javascript到底是不是单线程?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
JavaScript官方给出的答案是肯定的,它是单线程
那为什么还会有ajax异步发送和回调请求呢,而且serTimeout看起来也像是多线程的结果啊?
看这段代码
function foo(){console.log(1);setTimeout(function(){console.log(2)},5)}for(var i=0;i<100;i++){foo();}
程序运行结果是输出完所有的“1”之后又把所有的“2”输出了,说好了5ms就要输出一次“2”呢,怎么不领了,下面进入讨论正题
JavaScript毫无疑问是单线程的
因为JS运行在浏览器的js引擎中,是单线程的,每个window一个JS线程,既然是单线程的,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码。而浏览器是事件驱动的(Event driven),浏览器中很多行为是异步(Asynchronized)的,会创建事件并放入执行队列中。javascript引擎是单线程处理它的任务队列,你可以理解成就是普通函数和回调函数构成的队列。当异步事件发生时,如mouse click, a timer firing, or an XMLHttpRequest completing(鼠标点击事件发生、定时器触发事件发生、XMLHttpRequest完成回调触发等),将他们放入执行队列,等待当前代码执行完成。
异步事件驱动
前面已经提到浏览器是事件驱动的(Event driven),浏览器中很多行为是异步(Asynchronized)的,例如:鼠标点击事件、窗口大小拖拉事件、定时器触发事件、XMLHttpRequest完成回调等。当一个异步事件发生的时候,它就进入事件队列。浏览器有一个内部大消息循环,Event Loop(事件循环),会轮询大的事件队列并处理事件。例如,浏览器当前正在忙于处理onclick事件,这时另外一个事件发生了(如:window onSize),这个异步事件就被放入事件队列等待处理,只有前面的处理完毕了,空闲了才会执行这个事件。setTimeout也是一样,当调用的时候,js引擎会启动定时器timer,大约xxms以后执行xxx,当定时器时间到,就把该事件放到主事件队列等待处理(浏览器不忙的时候才会真正执行)。
浏览器不是单线程的
虽然JS运行在浏览器中,是单线程的,每个window一个JS线程,但浏览器不是单线程的,比如会有如下线程
- JavaScript引擎线程
- 界面渲染线程
- 浏览器事件触发线程
- http请求线程
浏览器会单独开启一个轮询Event loop事件队列的线程,把需要执行的事件丢到js线程的事件队列中等待执行。
Ajax异步请求是否真的异步?
既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?
请求确实是异步的,这请求是由浏览器新开一个线程请求(见前面的浏览器多线程)。当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的事件处理队列中等待处理。当浏览器空闲的时候出队列任务被处理,JavaScript引擎始终是单线程运行回调函数。javascript引擎确实是单线程处理它的任务队列,能理解成就是普通函数和回调函数构成的队列。
总结一下,Ajax请求确实是异步的,这请求是由浏览器新开一个线程请求,事件回调的时候是放入Event loop单线程事件队列等候处理。
原文地址——http://www.cnblogs.com/Mainz/p/3552717.html
这篇关于javascript到底是不是单线程?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!