浅谈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.pagination.js 无刷新分页实现步骤分享
May 23 Javascript
关于js中for in的缺陷浅析
Dec 02 Javascript
多个jquery.datatable共存,checkbox全选异常的快速解决方法
Dec 10 Javascript
24款热门实用的jQuery插件推荐
Dec 24 Javascript
浅谈javascript属性onresize
Apr 20 Javascript
原生js实现移动端瀑布流式代码示例
Dec 18 Javascript
Node做中转服务器转发接口
Oct 18 Javascript
AngularJS 实现购物车全选反选功能
Oct 24 Javascript
JavaScript 下载svg图片为png格式
Jun 21 Javascript
详解jenkins自动化部署vue
May 14 Javascript
通过vue手动封装on、emit、off的代码详解
May 29 Javascript
JavaScript this指向相关原理及实例解析
Jul 10 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缓冲 output_buffering和ob_start使用介绍
2014/01/30 PHP
ThinkPHP视图查询详解
2014/06/30 PHP
PHP实现动态执行代码的方法
2016/03/25 PHP
php array_key_exists() 与 isset() 的区别
2016/10/24 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
php使用imagecopymerge()函数创建半透明水印
2018/01/25 PHP
Windows下wamp php单元测试工具PHPUnit安装及生成日志文件配置方法
2018/05/28 PHP
Laravel事件监听器用法实例分析
2019/03/12 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
另一个javascript小测验(代码集合)
2011/07/27 Javascript
用nodejs写的一个简单项目打包工具
2013/05/11 NodeJs
基于jquery实现的文字淡入淡出效果
2013/11/14 Javascript
jQuery中clone()方法用法实例
2015/01/16 Javascript
js实现超酷的照片墙展示效果图附源码下载
2015/10/08 Javascript
JavaScript实现的Tween算法及缓冲特效实例代码
2015/11/03 Javascript
利用jquery给指定的table动态添加一行、删除一行的方法
2016/10/12 Javascript
使用JS实现图片轮播的实例(前后首尾相接)
2017/09/21 Javascript
vue中render函数的使用详解
2018/10/12 Javascript
ES6 Proxy实现Vue的变化检测问题
2019/06/11 Javascript
Python多线程同步Lock、RLock、Semaphore、Event实例
2014/11/21 Python
使用IPython下的Net-SNMP来管理类UNIX系统的教程
2015/04/15 Python
详解Python实现按任意键继续/退出的功能
2016/08/19 Python
python DES加密与解密及hex输出和bs64格式输出的实现代码
2020/04/13 Python
Python图像处理二值化方法实例汇总
2020/07/24 Python
python根据用户需求输入想爬取的内容及页数爬取图片方法详解
2020/08/03 Python
python 用Matplotlib作图中有多个Y轴
2020/11/28 Python
美国一家专业的太阳镜网上零售商:Solstice太阳镜
2016/07/25 全球购物
英国家庭珠宝商:T. H. Baker
2018/02/08 全球购物
商务日语毕业生自荐信范文
2013/11/14 职场文书
会计自荐书
2013/12/02 职场文书
高中校园广播稿
2014/01/11 职场文书
2015年思想品德教学工作总结
2015/07/22 职场文书
预备党员的思想汇报,你真的会写吗?
2019/06/28 职场文书
pytorch 运行一段时间后出现GPU OOM的问题
2021/06/02 Python
Pyqt5将多个类组合在一个界面显示的完整示例
2021/09/04 Python
Java使用JMeter进行高并发测试
2021/11/23 Java/Android