Javascript是单线程的深入分析(转)

原文:

http://blog.csdn.net/talking12391239/article/details/21168489

Javascript是单线程的

因为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线程,但浏览器不是单线程的,例如Webkit或是Gecko引擎,都可能有如下线程:

  • javascript引擎线程
  • 界面渲染线程
  • 浏览器事件触发线程
  • Http请求线程

很多童鞋搞不清,如果js是单线程的,那么谁去轮询大的Event loop事件队列?答案是浏览器会有单独的线程去处理这个队列。

Ajax异步请求是否真的异步?

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

其实请求确实是异步的,这请求是由浏览器新开一个线程请求(见前面的浏览器多线程)。当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的事件处理队列中等待处理。当浏览器空闲的时候出队列任务被处理,JavaScript引擎始终是单线程运行回调函数。javascript引擎确实是单线程处理它的任务队列,能理解成就是普通函数和回调函数构成的队列。

总结一下,Ajax请求确实是异步的,这请求是由浏览器新开一个线程请求,事件回调的时候是放入Event loop单线程事件队列等候处理。

时间: 2024-10-17 06:18:03

Javascript是单线程的深入分析(转)的相关文章

[转]Javascript是单线程的深入分析

Javascript是单线程的深入分析 面试的时候发现99%的童鞋不理解为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?还有non-blocking IO, event loop等概念很不清楚.来深入分析一下: 首先看下面的代码: function foo() { console.log( 'first' ); setTimeout( ( function(){ console.log( 'second' ); } ), 5);

Javascript是单线程的深入分析

本来想总结一下的,网上却发现有人已经解释的很清楚了,特转过来. 这也解释了为什么在用自动化测试工具来运行dumrendtree时设定的超时和测试case设定的超时的关联性. 面试的时候发现99%的童鞋不理解为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?还有non-blocking IO, event loop等概念很不清楚.来深入分析一下: 首先看下面的代码: 1 2 3 4 5 6 7 8 9 function foo()

Javascript引擎单线程机制及setTimeout执行原理说明

setTimeout用法在实际项目中还是会时常遇到.比如浏览器会聪明的等到一个函数堆栈结束后才改变DOM,如果再这个函数堆栈中把页面背景先从白色设为红色,再设回白色,那么浏览器会认为DOM没有发生任何改变而忽略这两句话,因此我们可以通过setTimeout把“设回白色”函数加入下一个堆栈,那么就可以确保背景颜色发生过改变了(虽然速度很快可能无法被察觉). 总之,setTimeout增加了Javascript函数调用的灵活性,为函数执行顺序的调度提供极大便利. 然后,我们从基础的层面来看看:理解J

理解 Javascript 的单线程,着实不易

理解 Javascript 的单线程,着实不易. 比如,对于 C 系编程来说,写个 while(true) 不是什么令人紧张的事情.在 nodejs 中似乎也不会出什么意外,因为还有消息机制可以操控--这只是你对 nodejs 的幻觉,或者说,这只是我对 nodejs 的幻觉.若子进程写成这样的话: process.on('message', function() { while(true); }); process.on('SIGINT', function() { console.log('

关于javascript的单线程和异步的一些问题

关于js单线程和异步方面突然就糊涂了,看别人的文章越看越糊涂,感觉这方面是个坑,跳进去就不好跳出来.再去看,看着看着感觉自己明白了一些东西,也不知道对不对,反正是暂时把自己说服了,这样理解能理解的通,就总结了一下几个问题. 问题1:浏览器的线程与进程 看了很多资料,很多人对进程和线程是不加区分的,甚至上面说的说进程下面就改口为线程了.按我的理解进程是比线程大的一个概念,当一个程序运行就开辟单个或多个进程地址空间(IE.Firefox.Safari均是单进程模式,Chrome则上多进程大),然后各

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

浏览器中的js程序是单线程的,那异步调用是怎么实现的呢?计时器是靠谁实现的呢?单线程难道是一边执行程序一边计时吗? 好了 ----之前就有好多的疑问  ,现在按我的理解和大家说一说 一.JavaScript单线程 在浏览器中,执行JS程序只有一个线程,所以是单线程,所以执行顺序就是从上到下依次执行,同一段时间内只能有一段代码被执行.你可能会问,为什么不用多线程呢,这样不是更能充分利用CPU吗? ps:只能说早期的页面非常简单,所以我认为设计者没有考虑多线程的问题 (本人猜想的哈,勿喷!!).另外

Javascript的单线程和异步编程

运行时概念 下面的内容解释了一个理论上的模型.现代 JavaScript 引擎着重实现和优化了描述的几个语义. 可视化描述 栈 函数调用形成了一个栈帧. function foo(b) { var a = 10; return a + b + 11; } function bar(x) { var y = 3; return foo(x * y); } console.log(bar(7)); 当调用bar时,创建了第一个帧 ,帧中包含了bar的参数和局部变量.当bar调用foo时,第二个帧就被

我想这次我真的理解了 JavaScript 的单线程机制

今天面试的时候被问到一个问题,是关于 JS 异步的.当时我脑海中闪过了一个单线程的概念,但却没有把真正的原理阐述清楚.所以回来特意重新回顾了前面单线程和异步相关的一些知识点. 虽然之前学习的时候也接触了单线程模型相关的东西,但当时理解得并不是很清楚和明白.所以这道面试题也没有给出一语中的的答案.重新阅读阮一峰的 <JavaScript 运行机制详解>和我之前写的<setTimeout 异步与回调>之后.我决定重新写一篇博客来更加白话的总结 JS 的单线程机制和异步. 重演历史 -

JavaScript是单线程还是多线程(转)

多线程要考虑线程之间的资源抢占,死锁,冲突之类一系列问题.JavaScript作为一门客户端脚本,貌似没有多线程的一些列问题.那么JavaScript是单线程还是多线程?通过查资料总结了JavaScript运行的原理.如下: 一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. JavaScript的单线程,与它的用途有关.作为浏览器脚本语言,JavaScri