setTimeout和setInterval的深入理解


Posted in Javascript onNovember 08, 2013

大概半年前发表过一篇关于setTimeout和setInterval的文章,但是现在回去仔细一看发现其实存在很多不足以及错误。事实上,setTimeout和setInterval并没有我们字面上理解的那么简单。要真正掌握并理解这两个方法,还得从javascript的单线程机制说起。

【开门见山】setTimeout和setInterval是如何工作的呢?
我们知道,js是单线程执行的。所以其实setTimeout和setInterval所谓的“异步调用”事实上是通过将代码段插入到代码的执行队列中实现的。

而如何计算插入的时间点呢?自然是要用到我们所说的timer,也就是计时器。当执行setTimeout和setInterval的时候,timer会根据你设定的时间“准确”地找到代码的插入点。当队列“正常”地执行到插入点时,就触发timer callback,也就是我们设定的回调函数:

function fn() { 
/* 
here is some codes 
*/ 
setTimeout(function() {alert('ok!')},1000); 
}

上面这个例子就是我们通常的用法,应该容易理解。可是,timer真的能那么准确么?代码队列的执行真的能那么正常么?

【斩草除根】重新认识所谓的“异步”
刚刚已经知道,事实上setTimeout和setInterval只是简简单单地通过插入代码到代码队列来实现代码的延迟执行(或者说异步执行)。但是事实上所谓的异步只是一个假象——它同样运行在一个线程上!
那么问题就来了,要是在代码插入点前的代码执行时间超过了传入setTimeout或setInterval的设定时间会怎样呢?让我们来看看这段代码:

function fn() { 
setTimeout(function(){alert('can you see me?');},1000); 
while(true) {} 
}

你觉得这段代码的执行结果是什么呢?答案是,alert永远不会出现。
这是为什么呢?因为,while这段代码没有执行完,插入在后面的代码便永远不会执行。
综上所述,其实JS终归是单线程产物。无论如何“异步”都不可能突破单线程这个障碍。所以许多的“异步调用”(包括Ajax)事实上也只是“伪异步”而已。只要理解了这么一个概念,也许理解setTimeout和setInterval也就不难了。
Javascript 相关文章推荐
jquery获得下拉框值的代码
Aug 13 Javascript
javascript变量作用域使用中常见错误总结
Mar 26 Javascript
判断复选框是否被选中的两种方法
Jun 04 Javascript
js调试系列 断点与动态调试[基础篇]
Jun 18 Javascript
纯CSS3代码实现滑动开关效果
Aug 19 Javascript
JS组件Bootstrap按钮组与下拉按钮详解
May 10 Javascript
教你5分钟学会用requirejs(必看篇)
Jul 25 Javascript
vue select二级联动第二级默认选中第一个option值的实例
Jan 10 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
Apr 18 jQuery
基于jQuery实现无缝轮播与左右点击效果
May 13 jQuery
js中的数组对象排序分析
Dec 11 Javascript
基于Vue中使用节流Lodash throttle详解
Oct 30 Javascript
如何获取select下拉框的值(option没有及有value属性)
Nov 08 #Javascript
jquery ajax修改全局变量示例代码
Nov 08 #Javascript
IE8下String的Trim()方法失效的解决方法
Nov 08 #Javascript
编写js扩展方法判断一个数组中是否包含某个元素
Nov 08 #Javascript
jquery滚动条插件jScrollPane的使用介绍
Nov 08 #Javascript
JQ获取动态加载的图片大小的正确方法分享
Nov 08 #Javascript
用JS将搜索的关键字高亮显示实现代码
Nov 08 #Javascript
You might like
PHP新手上路(十一)
2006/10/09 PHP
Youku 视频绝对地址获取的方法详解
2013/06/26 PHP
php处理带有中文URL的方法
2016/07/11 PHP
tp5框架的增删改查操作示例
2019/10/31 PHP
js 无提示关闭浏览器页面的代码
2010/03/09 Javascript
JavaScript访问样式表代码
2010/10/15 Javascript
jquery 利用show和hidden实现级联菜单示例代码
2013/08/09 Javascript
JS预览图像将本地图片显示到浏览器上
2013/08/25 Javascript
js使用onmousemove和onmouseout获取鼠标坐标的方法
2015/03/31 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
Three.js学习之几何形状
2016/08/01 Javascript
JavaScript 详解预编译原理
2017/01/22 Javascript
详解vue2.0 transition 多个元素嵌套使用过渡
2017/06/19 Javascript
微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
2017/08/16 Javascript
angularjs的单选框+ng-repeat的实现方法
2018/09/12 Javascript
关于微信小程序登录的那些事
2019/01/08 Javascript
JavaScript实现的九种排序算法
2019/03/04 Javascript
python解析中国天气网的天气数据
2014/03/21 Python
利用Opencv中Houghline方法实现直线检测
2018/02/11 Python
Python如何使用argparse模块处理命令行参数
2019/12/11 Python
解决pyPdf和pyPdf2在合并pdf时出现异常的问题
2020/04/03 Python
django实现后台显示媒体文件
2020/04/07 Python
澳大利亚运动鞋商店:Platypus Shoes
2019/09/27 全球购物
大专计算机个人求职的自我评价
2013/10/21 职场文书
运动会入场解说词
2014/02/07 职场文书
内蒙古鄂尔多斯市市长寄语
2014/04/10 职场文书
校园安全演讲稿
2014/05/09 职场文书
员工保密承诺书
2014/05/28 职场文书
公司任命书模板
2014/06/06 职场文书
副主任竞聘演讲稿
2014/08/18 职场文书
2014院党委领导班子及其成员群众路线对照检查材料思想汇报
2014/10/04 职场文书
庆七一宣传标语
2014/10/08 职场文书
学校法制宣传日活动总结
2014/11/01 职场文书
2014年教学工作总结
2014/11/13 职场文书
神农溪导游词
2015/02/11 职场文书
MySQL 原理与优化之原数据锁的应用
2022/08/14 MySQL