浅谈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 相关文章推荐
javascript iframe中打开文件,并检测iframe存在否
Dec 28 Javascript
关于在IE下的一个安全BUG --可用于跟踪用户的系统鼠标位置
Apr 17 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
Apr 07 Javascript
浅谈angularJS 作用域
Jul 05 Javascript
javascript中对变量类型的判断方法
Aug 09 Javascript
Bootstrap框架实现广告轮播效果
Nov 28 Javascript
jQuery操作json常用方法示例
Jan 04 Javascript
jQuery实现动态删除LI的方法
May 30 jQuery
jquery 动态遍历select 赋值的实例
Sep 12 jQuery
微信小程序实现的动态设置导航栏标题功能示例
Jan 31 Javascript
Vue动态创建注册component的实例代码
Jun 14 Javascript
Vue实现push数组并删除的例子
Nov 01 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中curl_setopt函数用法实例分析
2015/04/16 PHP
PHP的Yii框架的基本使用示例
2015/08/21 PHP
php微信开发之上传临时素材
2016/06/24 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
ThinkPHP 整合Bootstrap Ajax分页样式
2016/12/23 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
2020/04/13 PHP
SlideView 图片滑动(扩展/收缩)展示效果
2010/08/01 Javascript
JavaScript生成随机字符串的方法
2015/03/19 Javascript
解决WordPress使用CDN后博文无法评论的错误
2015/12/15 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
input输入密码变黑点密文的实现方法
2017/01/09 Javascript
Javascript中类式继承和原型式继承的实现方法和区别之处
2017/04/25 Javascript
nodeJS模块简单用法示例
2018/04/21 NodeJs
vue.js使用v-model指令实现的数据双向绑定功能示例
2018/05/22 Javascript
JavaScript时间与时间戳的转换操作实例分析
2018/12/07 Javascript
在Vue项目中使用jsencrypt.js对数据进行加密传输的方法
2019/04/17 Javascript
vue:el-input输入时限制输入的类型操作
2020/08/05 Javascript
[03:45]Newbee战队出征西雅图 决战2016国际邀请赛
2016/08/02 DOTA
[39:07]LGD vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
[43:26]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第二场 11.20
2020/11/23 DOTA
python统计文本文件内单词数量的方法
2015/05/30 Python
Django框架中处理URLconf中特定的URL的方法
2015/07/20 Python
win10环境下python3.5安装步骤图文教程
2017/02/03 Python
详解python调度框架APScheduler使用
2017/03/28 Python
TensorFlow打印tensor值的实现方法
2018/07/27 Python
python文件操作之批量修改文件后缀名的方法
2018/08/10 Python
将python依赖包打包成window下可执行文件bat方式
2019/12/26 Python
python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法
2020/02/14 Python
新加坡网上美容店:Hermo新加坡
2019/06/19 全球购物
澳大利亚一站式数码相机商店:CameraPro
2020/03/09 全球购物
动态密码技术
2012/10/18 面试题
2015年财务人员个人工作总结
2015/07/27 职场文书
Nginx缓存设置案例详解
2021/09/15 Servers
深入讲解数据库中Decimal类型的使用以及实现方法
2022/02/15 MySQL
【海涛dota解说】DCG联赛第一周 LGD VS DH
2022/04/01 DOTA
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电