浅谈Javascript线程及定时机制


Posted in Javascript onJuly 02, 2015

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 相关文章推荐
jQuery.Validate 使用笔记(jQuery Validation范例 )
Jun 25 Javascript
鼠标经过显示二级菜单js特效
Aug 13 Javascript
跟我学习javascript的undefined与null
Nov 17 Javascript
javascript对象的创建和访问
Mar 08 Javascript
详解javascript事件绑定使用方法
Oct 20 Javascript
node.js自动上传ftp的脚本分享
Jun 16 Javascript
vue使用ElementUI时导航栏默认展开功能的实现
Jul 04 Javascript
layui select获取自定义属性方法
Aug 15 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
Sep 07 Javascript
vue 使用vue-i18n做全局中英文切换的方法
Oct 29 Javascript
解决Vue在封装了Axios后手动刷新页面拦截器无效的问题
Nov 08 Javascript
Vue列表如何实现滚动到指定位置样式改变效果
May 09 Javascript
JavaScript获得url查询参数的方法
Jul 02 #Javascript
js跨域请求的5中解决方式
Jul 02 #Javascript
JS实现从连接中获取youtube的key实例
Jul 02 #Javascript
由ReactJS的Hello world说开来
Jul 02 #Javascript
深入理解JavaScript的React框架的原理
Jul 02 #Javascript
javascript实现简单的进度条
Jul 02 #Javascript
JavaScript实现添加、查找、删除元素
Jul 02 #Javascript
You might like
php图片裁剪函数
2018/10/31 PHP
JavaScript 学习初步 入门教程
2010/03/25 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
2013/02/02 Javascript
javascript通过className来获取元素的简单示例代码
2014/01/10 Javascript
Javascript实现商品秒杀倒计时(时间与服务器时间同步)
2015/09/16 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
2016/09/28 Javascript
jquery网页日历显示控件calendar3.1使用详解
2016/11/24 Javascript
JS操作input标签属性checkbox全选的实现代码
2017/03/02 Javascript
vue中子组件的methods中获取到props中的值方法
2018/08/27 Javascript
微信小程序保存多张图片的实现方法
2019/03/05 Javascript
[01:16:37]【全国守擂赛】第三周决赛 Dark Knight vs. 一个弱队
2020/05/04 DOTA
Python解析网页源代码中的115网盘链接实例
2014/09/30 Python
Python中用altzone()方法处理时区的教程
2015/05/22 Python
pygame实现简易飞机大战
2018/09/11 Python
python画柱状图--不同颜色并显示数值的方法
2018/12/13 Python
Python实现多态、协议和鸭子类型的代码详解
2019/05/05 Python
pandas数据筛选和csv操作的实现方法
2019/07/02 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
PyTorch中 tensor.detach() 和 tensor.data 的区别详解
2020/01/06 Python
PyQt中使用QtSql连接MySql数据库的方法
2020/07/28 Python
python 动态绘制爱心的示例
2020/09/27 Python
远程Wi-Fi宠物监控相机:Petcube
2017/04/26 全球购物
工商管理实习自我鉴定
2013/09/28 职场文书
毕业学生推荐信
2013/12/01 职场文书
最新的互联网创业计划书
2014/01/10 职场文书
《雷雨》教学反思
2014/02/20 职场文书
党员承诺书范文
2014/05/19 职场文书
售房委托书
2014/08/30 职场文书
市委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
2014年企业党支部工作总结
2014/12/04 职场文书
2015幼儿园庆元旦活动方案
2014/12/09 职场文书
就业推荐表自我评价范文
2015/03/02 职场文书
2015年学校总务处工作总结
2015/05/19 职场文书
闪闪的红星观后感
2015/06/08 职场文书
Golang二维数组的使用方式
2021/05/28 Golang
PHP中国际化的字符串排序和比较对象详解
2021/08/23 PHP