setTimeout,setInterval原理
function a() {
setTimeout(function(){alert(1)},0);
alert(2);
}
a();
和其他的编程语言一样,Javascript中的函数调用也是通过堆栈实现的。在执行函数a的时候,a先入栈,如果不给alert(1)加setTimeout,那么alert(1)第2个入栈,最后是alert(2)。但现在给alert(1)加上setTimeout后,alert(1)就被加入到了一个新的堆栈中等待,并”尽可能快“的执行。这个尽可能快就是指在a的堆栈完成后就立刻执行,因此实际的执行结果就是先alert(2),再alert(1)。在这里setTimeout实际上是让alert(1)脱离了当前函数调用堆栈。
利用这一点,javascript实际上是有多个线程的。
问题是: 多个setTimeout 是 分别放在不同的堆栈吗?如果是,那么我们就真的有了多线程的基础了
另一篇文章中的阐述。哪个是对的呢?
javascript线程解释(setTimeout,setInterval你不知道的事)
setTimeout( function(){ alert(’你好!’); } , 0);
setInterval( callbackFunction , 100);
同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!
div.onclick = function(){
setTimeout( function(){document.getElementById(’inputField’).focus();}, 0);
};
setTimeout( function(){ while(true){} } , 100);
setTimeout( function(){ alert(’你好!’); } , 200);
setInterval( callbackFunction , 200);
JavaScript引擎是单线程运行的,浏览器无论在什么时候都有且只有一个线程在运行JavaScript程序.
JavaScript引擎用单线程运行也是有意义的,单线程不必理会线程同步这些复杂的问题,问题得到简化
那么单线程的JavaScript引擎是怎么配合浏览器内核处理这些定时器和响应浏览器事件的呢?下面结合浏览器内核处理方式简单说明
浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步。假如某一浏览器内核的实现至少有三个常驻线程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些以外,也有一些执行完就终止的线程,如Http请求线程,这些异步线程都会产生不同的异步事件,下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的,虽然每个浏览器内核实现细节不同,但这其中的调用原理都是大同小异

所以,在脚本中执行对界面进行更新操作,如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来,这些操作将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来。
同理,还是在t1时间段内,接下来某个setInterval定时器也被添加了,由于是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理。
如果队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务,在任务没返回前队列中的其它任务是没法被执行的.
相信您现在已经很清楚JavaScript是否可多线程,也理解JavaScript定时器运行机制了,下面我们来对一些案例进行分析:
案例1:setTimeout与setInterval
setTimeout(function(){
/* 代码块... */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/*代码块... */
}, 10);
这两段代码看一起效果一样,其实非也
第一段中回调函数内的setTimeout是JavaScript引擎执行后再设置新的setTimeout 定时(此时会把代码插入任务队列),假定上一个回调处理完到下一个回调开始处理为一个时间间隔,理论两个setTimeout回调执行时间间隔>=10ms。setTimeout好处就是严格保证每隔一段时间执行代码。
第二段自setInterval设置定时后,定时触发线程就会源源不断的每隔十秒产生异步定时事件并放到任务队列尾,理论上两个setInterval 回调执行时间间隔<=10,这就可能导致上一段代码执行完毕后立即执行下一段代码,不会出现想象中的间隔一段时间再执行
其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行 onreadystatechange所设置的函数.
setTimeout(function(a,b,c){
console.log(a);//a
console.log(b);//b
console.log(c);//c
},0,3,4,5);
setInterval(function(a,b,c){
console.log(a);//b
console.log(b);//b
console.log(c);//c
},0,3,4,5);
setTimeout,setInterval原理的更多相关文章
- setTimeout,setInterval你不知道的…
javascript线程解释(setTimeout,setInterval你不知道的事) 标签: javascript引擎任务浏览器functionxmlhttprequest 2011-11-21 ...
- setTimeout,setInterval你不知道的事
javascript线程解释(setTimeout,setInterval你不知道的事) 标签: javascript引擎任务浏览器functionxmlhttprequest 2011-11-21 ...
- js异步处理工作机制(setTimeout, setInterval)
经常谈到异步,但是发现自己一直没深入理解setTimeout, setInterval,逛论坛的时候发现了这篇好文章,分享一下. ————————————————————以下为原文—————————— ...
- Javascript引擎的单线程机制和setTimeout执行原理阐述
工作中使用setTimeout解决了一个问题,于是对setTimeout的相关资料整理了下,以及对js引擎执行的原理一并整理了下,希望能给码农们一些帮助.若发现有错的地方大家及时指出,共同学习进步. ...
- setTimeout 实现原理, 机制
setTimeout 实现原理, 机制 JS 执行机制说起 浏览器(或者说 JS 引擎)执行 JS 的机制是基于事件循环. 由于 JS 是单线程,所以同一时间只能执行一个任务,其他任务就得排队,后续任 ...
- js,onblur后下一个控件获取焦点判断、html当前活跃控件、jquery版本查看、jquery查看浏览器版本、setTimeout&setInterval
需求: input控件在失去焦点后直接做验证,验证通不过的话,显示相应错误.但是如果失去焦点后点击的下个控件是比较特殊的控件(比如,退出系统),那么不执行验证操作,直接退出系统(防止在系统退出前,还显 ...
- setTimeout/setInterval执行时机
setTimeout()和setInterval()经常被用来处理延时和定时任务.setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则可以在每隔指定的 ...
- js中setTimeout/setInterval定时器用法示例
js中setTimeout(定时执行一次)和setInterval(间隔循环执行)用法介绍. setTimeout:在指定的毫秒数后调用指定的代码段或函数:setTimeout示例代码 functio ...
- 管理页面的 setTimeout & setInterval
在管理 setTimeout & setInterval 这两个 APIs 时,笔者通常会在顶级(全局)作用域创建一个叫 timer 的对象,在它下面有两个数组成员 —— {sto, siv} ...
随机推荐
- gulp安装说明
1.安装node-v6.3.0-x64,安装成功后再点击node-v6.3.0-x64卸载(点击remove). 2.安装node-v4.4.7-x64. 3.打开cmd命令行,输入node -v,查 ...
- 委托的N种写法,你喜欢哪种?
一.委托调用方式 1. 最原始版本: delegate string PlusStringHandle(string x, string y); class Program { static void ...
- Android—实现自定义相机倒计时拍照
这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能 首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件: 两个TextView是用来显示提示信息和倒计时的 ...
- IOS开发基础知识--碎片38
1:FCUUID获取设备标识的运用 a:作者 githun地址 https://github.com/fabiocaccamo/FCUUID 因为里面还用到作者的另外一个类UICKeyChainSto ...
- 了解HTML 元素分类
HTML中包含大量的标签, 这些标签在我们使用中发现会有小小的差别, 有的标签用了之后不会有太大的布局变化, 只是语义化, 而有的标签却会重起一行, 相当于自己回车了一次, 这就是不同标签元素的分类不 ...
- 【产品 & 设计】入门 - 工具篇 - Sketch + Skala Preview
前言 做产品和设计快 1 年了,积累了一点经验分享一下 —— 抛砖引玉,欢迎交流. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: ht ...
- routes.rb和link_to的一些规则
rails文档中描述了一个知识,link_to方法用于产生链接,但链接是根据routes.rb中的路由规则来产生的.这又分为面向资源和非面向资源两种产生链接的方法.比如 routes.rb文件中有两条 ...
- Windows下使用Xshell建立反向隧道
反向隧道是一个进行内网穿透的简单而有用的方法.在Linux下通过OpenSSH和AutoSSH可以很容易地建立稳定的反向隧道.但是在Windows下,还能看到有人特意装个Cygwin来运行这些工具…… ...
- mongo学习笔记(一):增删改查
安装:我是按这篇来弄的 一.Insert 1.db.person.insert({"name":"jack","age":20}) 2.va ...
- day1 基础总结
学习博客地址: http://www.cnblogs.com/alex3714/articles/5465198.html 低级语言:接近硬件底层 高级语言:接近用户思维 编程语言: 1. 编译型:c ...