Javascript线程及定时机制
setTimeout、setInterval的使用
Javascript api文档中定义setTimeout和setInterval第二个参数意义分别为间隔多少毫秒后回调函数被执行和每隔多少毫秒回调函数被执行。但随着工作经验的积累,我们发现事实并非如此。
比如
div.onclick=function(){
setTimeout(function(){
document.getElementById('input').focus();
},0);
}
就解释不通了,立即执行就立即执行呗,干嘛还要设置个定时兜个圈子呢。
又有一天你写了下面一段代码
setTimeout(function(){while(true){}},100);
setTimeout(function(){alert('你好');},200);
第一行代码死循环,结果造成第二行alert始终没有出现,为啥哩?
单线程or多线程?
原来,Javascript引擎是单线程运行的,浏览器只有一个线程在运行JavaScript程序。因为单线程的设计,所以免去了复杂的多线程同步问题。
当设置一个定时的时候,浏览器会在设定的时间后将你指定的回调函数插入任务序列,而非立即执行。如果设定定时时间为0,表示立即插入任务序列,而不是立即执行,仍然要等队列中任务执行完毕,轮到你,你才执行。
所以下面代码先弹出2,再弹出1
setTimeout(function(){
alert(1);
},0);
alert(2);
那么,这又有什么实际用途呢?且看下面示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>setTimeout 0</title>
</head>
<body>
输入字符,但内容却不能实时显示<input type="text" onkeydown="show(this.value)"/> <br/>
输入字符,内容能实时显示<input type="text" onkeydown="var self=this;setTimeout(function(){show(self.value)},0)"/>
<div></div>
<script>
function show(val){
document.getElementsByTagName("div")[0].innerHTML=val;
}
</script>
</body>
</html>
这个例子中,js引擎需要执行keydown事件处理程序,然后更新输入框的value值。事件处理程序执行时,更新value的任务只能进入队列等待,所以keydown事件执行时无法得到更新后的value值;但通过setTimeout我们把取value的操作放入队列,并在更新value之后执行,所以内容就能实时显示了。
再回来看看下面的代码:
setTimeout(function(){
//do something...
setTimeout(arguments.callee,10);
},10);
setInterval(function(){
//do something...
},10);
这两段代码看起来效果一样,是不是。其实还是有区别的,第一段的回调函数内的setTimeout是js引擎执行后再设定的新的定时,假定从上一个回调处理完到下一个回调开始为一个时间间隔,理论上时间间隔>=10ms,后一段代码<=10ms。
说到这儿,那XMLHttpRequest是不是真的异步呢?是的,请求是异步的,不过这请求是浏览器新开的一个线程。当请求的状态变更时,如果先前已设置回调,异步线程就将状态变更事件放入js引擎处理队列中等待处理,当任务被处理时js引擎始终还是单线程地执行onreadystatechange所设置的函数的。
Javascript线程及定时机制的更多相关文章
- 关于JavaScript定时机制的总结
要理解JavaScript的定时机制,就要知道JavaScript的运行机制. 首先声明,JavaScript是单线程运行(JavaScript引擎线程)事件驱动. 一.浏览器中有多个线程 一款浏览器 ...
- JavaScript可否多线程? 深入理解JavaScript定时机制
JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( ...
- 深入理解JavaScript定时机制和定时器注意问题
容易欺骗别人感情的JavaScript定时器 JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不 ...
- 阅读《深入理解JavaScript定时机制》
鸟哥的这篇<深入理解JavaScript定时机制>从javascript线程角度分析了setTimeout和setInterval两个定时触发器的实现原理. 看完的体验就是主要要记住两点: ...
- JavaScript可否多线程? 深入理解JavaScript定时机制(转载)
说明:最近写 js 时需要用setinterval函数做定时操作,谁知道,刚开始后运行完好,但一段时间后他就抽风了,定时任务运行的时间间隔越来越短,频率加快,这是一个完全不能容忍的问题,带着一个可以出 ...
- JavaScript定时机制setTimeout与setInterval研究
JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( ...
- 转:JavaScript定时机制、以及浏览器渲染机制 浅谈
昨晚,朋友拿了一道题问我: a.onclick = function(){ setTimeout(function() { //do something ... },0); }; //~~~ 我只知道 ...
- JavaScript定时机制、以及浏览器渲染机制 浅谈
昨晚,朋友拿了一道题问我: a.onclick = function(){ setTimeout(function() { //do something ... },0); }; JavaScript ...
- 深入理解JavaScript定时机制
容易欺骗别人感情的JavaScript定时器 JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不 ...
随机推荐
- opencv 中文文档地址
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html
- OSI 七层模型和 TCP/IP 协议比较
OSI (Open System Interconnection), 开放式系统互联参考模型.从下到上七层模型功能及其代表协议: 物理层(Physical) :规定了激活.维持.关闭通信端点之间的 ...
- Yii框架zii.widgets.grid自定义按钮,ajax触发事件并提示
相关类手册: http://www.yiichina.com/api/CButtonColumn buttons 属性 public array $buttons; the configurati ...
- 上海Uber优步司机奖励政策(2月1日~2月7日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- JavaEE自定义标签:标签类的创建、tld配置文件的创建(位置、如何创建)、Web-XML配置、JSP应用
1.标签 以类似于html标签的方式实现的java代码的封装. 第一:形成了开发标签的技术标准---自定义标签的技术标准. 第二:java标准标签库(sun之前自己开发的一系列的标签的集合)jstl, ...
- Linux进程管理—信号、定时器
信号: 1. 信号的作用: 背景: 进程之间通信比较麻烦. 但进程之间又必须通信,比如父子进程之间. 作用: 通知其他进程响应.进程之间的一种通信机制. 信号: 接受信号的进程马上停止,调 ...
- SVG(可扩展矢量图)系列教程
本系列教程同步至博客www.waylau.com 从新往久排序,持续更新 SVG与JS交互实例之画板 SVG <marker>创建箭头 SVG实例之中国地图 SVG实例之电力开关 SVG ...
- [转]开源应用架构之asterisk
作者:Russell Bryant 翻译:jiazhengfeng Asterisk[1]是一款GPLv2协议下的开源电话应用平台.简单来说,Asterisk是一个服务器应用,能够完成发起电话呼叫.接 ...
- hadoop错误org.apache.hadoop.mapred.MapTask$NewOutputCollector@17bda0f2
错误: org.apache.hadoop.mapred.MapTask$NewOutputCollector@17bda0f2 java.io.IOException: Spill failed 错 ...
- 把QQ聊天记录插入数据库中
最近在做毕设,其中一个环节是分析qq聊天记录,在分析之前需要先把qq聊天记录导出,然后存入数据库中,qq聊天记录导出后是文本文档,导出方式: 1.登录qq后,点击任意一个好友,查看与他的聊天记录,点击 ...