浅谈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中两个感叹号的作用说明
Dec 28 Javascript
javascript弹出层输入框(示例代码)
Dec 11 Javascript
8个实用的jQuery技巧
Mar 04 Javascript
Javascript WebSocket使用实例介绍(简明入门教程)
Apr 16 Javascript
node.js发送邮件email的方法详解
Jan 06 Javascript
vue动态组件实现选项卡切换效果
Mar 08 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
Jul 31 Javascript
javascript实现电脑和手机版样式切换
Nov 10 Javascript
ES6模板字符串和标签模板的应用实例分析
Jun 25 Javascript
layer实现登录弹框,登录成功后关闭弹框并调用父窗口的例子
Sep 11 Javascript
微信小程序网络请求实现过程解析
Nov 06 Javascript
JavaScript之Blob对象类型的具体使用方法
Nov 29 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实现图片添加水印功能
2014/02/13 PHP
PHP实现GIF图片验证码
2015/11/04 PHP
Laravel框架自定义分页样式操作示例
2020/01/26 PHP
记录几个javascript有关的小细节
2007/04/02 Javascript
js限制textarea每行输入字符串长度的代码
2012/10/31 Javascript
JS取文本框中最小值的简单实例
2013/11/29 Javascript
JSONP跨域的原理解析及其实现介绍
2014/03/22 Javascript
jQuery+css实现的时钟效果(兼容各浏览器)
2016/01/27 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
Vue2.0基于vue-cli+webpack Vuex的用法(实例讲解)
2017/09/15 Javascript
vue组件生命周期详解
2017/11/07 Javascript
微信开发之企业付款到银行卡接口开发的示例代码
2018/09/18 Javascript
微信小程序城市选择及搜索功能的方法
2019/03/22 Javascript
CKeditor4 字体颜色功能配置方法教程
2019/06/26 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
python通过自定义isnumber函数判断字符串是否为数字的方法
2015/04/23 Python
详解Swift中属性的声明与作用
2016/06/30 Python
Python动态生成多维数组的方法示例
2018/08/09 Python
python同时遍历数组的索引和值的实例
2018/11/15 Python
python实现复制文件到指定目录
2019/10/16 Python
利用python批量爬取百度任意类别的图片的实现方法
2020/10/07 Python
对Pytorch 中的contiguous理解说明
2021/03/03 Python
分享一个H5原生form表单的checkbox特效代码
2018/02/26 HTML / CSS
加拿大约会网站:EliteSingles.ca
2018/01/12 全球购物
浙大网新C/C++面试解惑
2015/05/27 面试题
《十六年前的回忆》教学反思
2014/02/14 职场文书
仓管员岗位责任制
2014/02/19 职场文书
企业法人代表任命书
2014/06/06 职场文书
2014年党员自我评议总结
2014/09/23 职场文书
公司股份合作协议书
2014/12/07 职场文书
2015元旦节寄语
2014/12/08 职场文书
产品质量保证书范本
2015/02/27 职场文书
MySQL 分组查询的优化方法
2021/05/12 MySQL
CSS实现切角+边框+投影+内容背景色渐变效果
2021/11/01 HTML / CSS
SONY600GR,国产收音机厂商永远的痛
2022/04/05 无线电
Python Numpy库的超详细教程
2022/04/06 Python