浅谈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 相关文章推荐
JScript内置对象Array中元素的删除方法
Mar 08 Javascript
js toFixed()方法的重写实现精度的统一
Mar 06 Javascript
ECMAScript 5中的属性描述符详解
Mar 02 Javascript
学习JavaScript设计模式之观察者模式
Apr 22 Javascript
js css实现垂直方向自适应的三角提示菜单
Jun 26 Javascript
浅谈javascript中的三种弹窗
Oct 21 Javascript
Vue组件开发初探
Feb 14 Javascript
JavaScript基础之this详解
Jun 04 Javascript
vue组件中使用iframe元素的示例代码
Dec 13 Javascript
原生JS检测CSS3动画是否结束的方法详解
Jan 27 Javascript
vue vant Area组件使用详解
Dec 09 Javascript
详解Typescript 内置的模块导入兼容方式
May 31 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
延长phpmyadmin登录时间的方法
2011/02/06 PHP
PHP利用hash冲突漏洞进行DDoS攻击的方法分析
2015/03/26 PHP
thinkPHP5框架分页样式类完整示例
2018/09/01 PHP
鼠标移动到图片名上,显示图片的简单实例
2013/07/14 Javascript
jquery复选框全选/取消示例
2013/12/30 Javascript
关于Javascript加载执行优化的研究报告
2014/12/16 Javascript
使用Node.js实现HTTP 206内容分片的教程
2015/06/23 Javascript
Javascript闭包实例详解
2015/11/29 Javascript
Jquery揭秘系列:ajax原生js实现详解(推荐)
2016/06/08 Javascript
JS实现电商放大镜效果
2017/08/24 Javascript
JavaScript设计模式之单例模式简单实例教程
2018/07/02 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
vue自动路由-单页面项目(非build时构建)
2019/04/30 Javascript
基于layui框架响应式布局的一些使用详解
2019/09/16 Javascript
JS回调函数简单易懂的入门实例分析
2019/09/29 Javascript
JS实现普通轮播图特效
2020/01/01 Javascript
通过实例浅析Python对比C语言的编程思想差异
2015/08/30 Python
Python closure闭包解释及其注意点详解
2019/08/28 Python
Python嵌套函数,作用域与偏函数用法实例分析
2019/12/26 Python
Python装饰器实现方法及应用场景详解
2020/03/26 Python
Python小白不正确的使用类变量实例
2020/05/29 Python
Python3中的tuple函数知识点讲解
2021/01/03 Python
分享30个新鲜的CSS3打造的精美绚丽效果(附演示下载)
2012/12/28 HTML / CSS
三星美国官网:Samsung美国
2017/02/06 全球购物
Swisse官方海外旗舰店:澳大利亚销量领先,自然健康品牌
2017/12/15 全球购物
Allsole美国/加拿大:英国一家专门出售品牌鞋子的网站
2018/10/21 全球购物
美国最佳选择产品网站:Best Choice Products
2019/05/27 全球购物
意大利网上药房:Farmacia 33
2020/01/27 全球购物
好的自荐信包括什么内容
2013/11/07 职场文书
清洁工表扬信
2014/01/08 职场文书
党员自我批评与反省材料
2014/02/10 职场文书
工作推荐信范文
2014/05/10 职场文书
企业财务经理岗位职责
2015/04/08 职场文书
2015人事行政工作总结范文
2015/05/21 职场文书
干货:如何写好工作计划!
2019/05/17 职场文书
PHP使用非对称加密算法RSA
2021/04/21 PHP