谈谈Javascript线程
其实,大家都知道Javascript的语言执行环境是单线程的,浏览器无论在什么时候都有且只有一个线程在运行Javascript程序。那Ajax发送异步请求怎么解释,setTimeout/setInterval定时执行回调函数又是怎么解释呢?
要说解释清楚这些问题,还得从浏览器内核处理定时器(setTimeout、setInterval)和响应浏览器事件说起。
浏览器内核允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步。浏览器内核的实现至少有三个常驻线程:javascript引擎线程、GUI渲染线程、浏览器事件触发线程。除些以外,也有一些执行完就终止的线程:如Http请求线程等,这些异步线程都会产生不同的异步事件。
我们可以通过下面这张图来理解JavaScript引擎与另外那些线程之间的通信机制。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" >
<title>测试</title>
<style>
*{margin:0;padding:0}
body{background-color:#000000; color: #ffffff}
</style>
</head> <body>
<script type="text/javascript">
setTimeout(function(){
while(true){
console.log("Do first CallBack");
}
},1000);
setInterval(function(){
console.log("Do second CallBack_____"+new Date().getTime());
},2000);
</script>
</body>
</html>

执行结果告诉我们,setInterval的回调函数一直没有被执行,在执行setTimeout回调函数是发生阻塞,导致执行队列后面的回调函数无法执行。
假如代码的调用方式是 setTimeout(func, 100),那么该代码被执行 100 毫秒之后,定时器的事件被触发。如果这个时候 JavaScript 引擎没有正在执行的其它代码,则与此定时器对应的 JavaScript 方法 func就可以被执行。否则的话,该 JavaScript 方法的执行就被加入到等待的队列中。当 JavaScript 引擎空闲的时候,会从这个队列中选择一个等待的 JavaScript 方法来执行。也就是说,虽然在调用 setTimeout()的时候设置的间隔时间是 100 毫秒,与之对应的 JavaScript 方法实际被执行的间隔有可能大于设定的 100 毫秒,取决于是否有其它代码正在被执行和执行所花费的时间。因此 setTimeout()的实际生效的间隔时间可能大于设定的时间。
而 setInterval()的执行方式与 setTimeout()有很大不同。假如代码的调用方式是 setInterval(func, 100),则每隔 100 毫秒,定时器的事件就会被触发。与 setTimeout()相同的是,如果当前 JavaScript 引擎空闲的话,则定时器对应的方法 func会被立即执行。否则的话,该 JavaScript 方法的执行就会被加入到等待队列中。由于定时器的事件是每隔 100 毫秒就触发一次,有可能某一次事件触发的时候,上一次事件的处理方法还没有机会得到执行,仍然在等待队列中。这个时候,这个新的定时器事件就被丢弃。需要注意的是,由于 JavaScript 引擎的这种执行方式,有可能定时器事件处理方法的两次被执行的实际时间间隔小于设定的间隔。比如上一个定时器事件的处理方法触发之后,等待了 50 毫秒才获得被执行的机会。而第二个定时器事件的处理方法被触发之后,马上就被执行了。那么这两者之间的时间间隔实际上只有 50 毫秒。因此,setInterval()并不适合实现精确的按固定间隔的调度操作。
总的来说,使用 setTimeout()和 setInterval()的时候,都不能满足精确的时间间隔。通过 setTimeout()设置的 JavaScript 方法的实际执行间隔时间不小于设定的时间,而通过 setInterval()设置的重复执行的 JavaScript 方法的间隔可能会小于设定的时间。
推荐一篇博客:How Javascript Timers Work.
谈谈Javascript线程的更多相关文章
- setTimeout setInterval 区别 javascript线程解释
原文:http://www.iamued.com/qianduan/1645.html 今天看到这篇文章,学到了不少东西 特此发出来 和大家分享 JavaScript的setTimeout与setIn ...
- javascript线程解释(setTimeout,setInterval你不知道的事)---转载
在工作中,可能我们经常遇到在有很多 setInterval 的页面, 再手动触发 setTimeout 的时候经常失败, 尤其是 jquery做动画的时候,一些渐入溅出的东西,很多东西都不被触发……, ...
- 再看JavaScript线程
继上篇讨论了一些关于JavaScript线程的知识,我们不妨回过头再看看,是不是JavaScript就不能多线程呢?看下面一段很简单的代码(演示用,没考虑兼容问题): 代码判断一: <div i ...
- javascript线程解释(setTimeout,setInterval你不知道的事)
john resig写的一篇文章: 原文地址:http://ejohn.org/blog/how-javascript-timers-work/ 作为入门者来说,了解JavaScript中timer的 ...
- 谈谈javaScript
谈谈javaScript (杰我学习) 一. 什么是JavaScript 人们通常所说的JavaScript,其正式名称为ECMAScript.这个标准由ECMA组织发展和维护.ECMA ...
- 《windows核心编程系列》十五谈谈windows线程栈
谈谈windows线程栈. 当系统创建线程时会为线程预订一块地址空间区域,注意仅仅是预订.默认情况下预定的这块区域的大小是1MB,虽然预订这么多,但是系统并不会给全部区域调拨物理存储器.默认情况下,仅 ...
- JavaScript线程
JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( ...
- 谈谈javascript中的prototype与继承
谈谈javascript中的prototype与继承 今天想谈谈javascript中的prototype. 通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性 ...
- Java:谈谈控制线程的几种办法
目录 Java:谈谈控制线程的几种办法 join() sleep() 守护线程 主要方法 需要注意 优先级 弃用三兄弟 stop() resume suspend 中断三兄弟 interrupt() ...
随机推荐
- Android 带着用户名的SharedPreferences
/** * 设置当前用户的签到信息 * account&info;account&info * * @param context * @param sign * @author jrj ...
- java的异常处理机制(try…catch…finally)
1 引子try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的“教训”告诉我,这个东西可不是想象中的那么简单.听话.不信 ...
- 用if else 判断是不是7的倍数等
static void Main(string[] args) { while (true) { int b; ...
- 百万程序员的苦恼-选择VB.NET还是C#
在过去的一年中,互联网上的各大讨论区或者电子邮件的讨论列表都对微软的VB.NET以及C#的各种优越性做了探讨.这些讨论围绕的主要问题就是,我应该先学哪一个,VB.NET还是C#?? 我写这篇文章的目的 ...
- zabbix中文配置指南(转)-服务器监控
一.Zabbix简介 1.1 Zabbix简介 Zabbix是一个企业级的开源分布式监控解决方案,由一个国外的团队持续维护更新,软件可以自由下载使用,运作团队靠提供收费的技术支持赢利.官方网站:htt ...
- C# 线程知识--使用ThreadPool执行异步操作
C# 线程知识--使用ThreadPool执行异步操作 在应用程序中有许多复杂的任务,对于这些任务可能需要使用一个或多个工作线程或I/O线程来协作处理,比如:定时任务.数据库数据操作.web服务.文件 ...
- flume服务的搭建
搭建前先统一时间,关闭防火墙,使用的jar包版本是1.6.0的 服务配置有两种方式 第一种:具体步骤如下: 1.将jar包传至node1上,解压至根目录 2.更改目录名,使用如下命令:mv apach ...
- Spark系列(一)Spark1.0.0源码编译及安装
最近想对自己学的东西做些回顾,想到写博客是个不错的方式,方便他人也有利自己,刚开始写不足之处大家多担待. 编译前需要安装JDK1.6以上.scala.Maven.Ant.hadoop2.20 如下图( ...
- 【Java基础】成员变量和局部变量的区别
在类中的位置不同 成员变量:在类内部方法外部 局部变量:在方法体内部定义的或者方法的参数中定义的在内存中的位置不同 成员变量:在堆内存,有初始化值,byte,short,int,long->0, ...
- HDU4737 - A Bit Fun(线段树)
题目大意 给你一个数组a,定义f(i,j)=ai|ai+1|ai+2|⋯|aj ,|为or运算,求满足f(i,j)<m的二元组个数,N≤105,m≤230 题解 枚举起点i,然后找出最靠右的k, ...