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);
<strong>JavaScript引擎是单线程运行的,浏览器无论在什么时候都有且只有一个线程在运行JavaScript程序.
</strong>
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运行原理的更多相关文章
- JavaScript运行原理解析
原文:1.http://blog.csdn.net/liaodehong/article/details/50488098 2.Stack的三种含义 (阮一峰) 3. http://lib.csdn. ...
- setTimeout,setInterval你不知道的…
javascript线程解释(setTimeout,setInterval你不知道的事) 标签: javascript引擎任务浏览器functionxmlhttprequest 2011-11-21 ...
- setTimeout,setInterval你不知道的事
javascript线程解释(setTimeout,setInterval你不知道的事) 标签: javascript引擎任务浏览器functionxmlhttprequest 2011-11-21 ...
- Js基础知识(四) - js运行原理与机制
js运行机制 本章了解一下js的运行原理,了解了js的运行原理才能写出更优美的代码,提高运行效率,还能解决开发中遇到的不理解的问题. 进程与线程 进程是cpu资源分配的最小单位,进程可以包含多个线程. ...
- setTimeout/setInterval执行时机
setTimeout()和setInterval()经常被用来处理延时和定时任务.setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则可以在每隔指定的 ...
- javascript真的是异步的吗?且看setTimeout的实现原理以及setTimeout(0)的使用场景
在今天之前我一直以为setTimeout这个函数是异步的,无意中看到了一篇关于setTimeout的文章.发现自己曾经的认识全是错误的,赶紧总结下. 先看一段代码: var start = new D ...
- js异步处理工作机制(setTimeout, setInterval)
经常谈到异步,但是发现自己一直没深入理解setTimeout, setInterval,逛论坛的时候发现了这篇好文章,分享一下. ————————————————————以下为原文—————————— ...
- setTimeout的实现原理以及setTimeout(0)的使用场景
先看一段代码: var start = new Date(); setTimeout(function(){ var end = new Date(); console.log("Tim ...
- 【原创】分布式之数据库和缓存双写一致性方案解析(三) 前端面试送命题(二)-callback,promise,generator,async-await JS的进阶技巧 前端面试送命题(一)-JS三座大山 Nodejs的运行原理-科普篇 优化设计提高sql类数据库的性能 简单理解token机制
[原创]分布式之数据库和缓存双写一致性方案解析(三) 正文 博主本来觉得,<分布式之数据库和缓存双写一致性方案解析>,一文已经十分清晰.然而这一两天,有人在微信上私聊我,觉得应该要采用 ...
随机推荐
- MVCC的一些理解
link 一.MVCC简介 MVCC (Multiversion Concurrency Control),即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控 ...
- 系统内置委托:Func/Action
lSystem.Func 代表有返回类型的委托 lpublic delegate TResult Func<out TResult>(); lpublic delegate TResul ...
- weex Mac开发环境
安装: 1.java的jdk下载和安装 1-1.下载.安装:省略 1-2.配置 第一步:命令行内输入touch .bash_profile命令,生成.bash_profile的隐藏配置文件,用于配置j ...
- mac 安装mysql特种报错的对应解决方式
参考 :http://www.jianshu.com/p/776e72742c6e 原文废话太多了, 还是看我的好了. 配置环境变量 echo "export PATH=$PATH:/usr ...
- chrome console的使用 : 异常和错误的处理 – Break易站
本文内容来自:chrome console的使用 : 异常和错误的处理 – Break易站 利用 Chrome DevTools 提供的工具,您可以修复引发异常的网页和在 JavaScript 中调试 ...
- amaze UI 笔记 - JS
导航添加依据 http://amazeui.org/javascript 下面内容属学习笔记,如有理解偏差和错误请留言相告,感谢!* =(官网这块写的很详细) 一 .UI增强 1.警告框 显示可关闭的 ...
- AVFoundation 框架初探究(一)
夜深时动笔 前面一篇文章写了视频播放的几种基本的方式,算是给这个系列开了一个头,这里面最想说和探究的就是AVFoundation框架,很想把这个框架不敢说是完全理解,但至少想把它弄明白它里面到底有什么 ...
- canvas 简易的加载进度条
做一个web app,想在第一次或者更新的时候,有一个更新进度条,我个人比较喜欢圆的那种. canvas + svg高低配,应该还不错的.顺便一提,canvas用来压缩图片也是么么哒的. 先看下效果图 ...
- c#的unity
1.引用对象 2.在app.config中进行配置 <?xml version="1.0" encoding="utf-8" ?> <conf ...
- 【数论】洛谷P1313计算系数
题目描述 给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数. 输入输出格式 输入格式: 输入文件名为factor.in. 共一行,包含5 个整数,分别为 a ,b ,k , ...