浅谈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打开新窗口同时关闭旧窗口
Jan 16 Javascript
jQuery 美元符冲突的解决方法
Mar 28 Javascript
div+css布局的图片连续滚动js实现代码
May 04 Javascript
左右悬浮可分组的网站QQ在线客服代码(可谓经典)
Dec 21 Javascript
js的延迟执行问题分析
Jun 23 Javascript
jQuery中height()方法用法实例
Dec 24 Javascript
js实现的牛顿摆效果
Mar 31 Javascript
javascript 中关于array的常用方法详解
May 05 Javascript
Vue核心概念Getter的使用方法
Jan 18 Javascript
js实现一个页面多个倒计时的3种方法
Feb 25 Javascript
vue element-ui之怎么封装一个自己的组件的详解
May 20 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
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函数func_num_args用法实例分析
2015/12/07 PHP
Yii2前后台分离及migrate使用(七)
2016/05/04 PHP
Joomla简单判断用户是否登录的方法
2016/05/04 PHP
Windows2003下php5.4安装配置教程(IIS)
2016/06/30 PHP
PHP如何获取Cookie并实现模拟登录
2020/07/16 PHP
Javascript代码混淆综合解决方案-Javascript在线混淆器
2006/12/18 Javascript
jquery垂直公告滚动实现代码
2013/12/08 Javascript
Array栈方法和队列方法的特点说明
2014/01/24 Javascript
JavaScript获取一个范围内日期的方法
2015/04/24 Javascript
详解jquery事件delegate()的使用方法
2016/01/25 Javascript
JavaScript程序中实现继承特性的方式总结
2016/06/24 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
SVG描边动画
2017/02/23 Javascript
Vue组件通信实践记录(推荐)
2017/08/15 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
2018/02/23 Javascript
微信小程序实现时间预约功能
2018/11/27 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
2019/05/27 Javascript
javascript 原型与原型链的理解及实例分析
2019/11/23 Javascript
vue中提示$index is not defined错误的解决方式
2020/09/02 Javascript
Python3使用正则表达式爬取内涵段子示例
2018/04/22 Python
Python实现的本地文件搜索功能示例【测试可用】
2018/05/30 Python
python实现写数字文件名的递增保存文件方法
2018/10/25 Python
详解python中@的用法
2019/03/27 Python
基于Python爬取股票数据过程详解
2020/10/21 Python
碧欧泉美国官网:Biotherm美国
2016/08/31 全球购物
Footshop乌克兰:运动鞋的最大选择
2019/12/01 全球购物
C语言中break与continue的区别
2012/07/12 面试题
什么是符号链接,什么是硬链接?符号链接与硬链接的区别是什么?
2014/01/19 面试题
护士专业推荐信
2013/11/02 职场文书
平安工地建设方案
2014/05/06 职场文书
学校总务处领导干部个人对照检查材料思想汇报
2014/10/06 职场文书
领导批评与自我批评范文
2014/10/16 职场文书
2015年会计个人工作总结
2015/04/02 职场文书
禁毒主题班会教案
2015/08/14 职场文书
创业计划书之DIY自助厨房
2019/09/06 职场文书
如何创建一个创建MySQL数据库中的datetime类型
2022/03/21 MySQL