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 相关文章推荐
[推荐]javascript 面向对象技术基础教程
Mar 03 Javascript
jQuery源码中的chunker 正则过滤符分析
Jul 31 Javascript
js函数中onmousedown和onclick的区别和联系探讨
May 19 Javascript
jQuery中wrapAll()方法用法实例
Jan 16 Javascript
jquery解析json格式数据的方法(对象、字符串)
Nov 24 Javascript
zepto与jquery的区别及zepto的不同使用8条小结
Jul 28 Javascript
Vue.js仿Metronic高级表格(二)数据渲染
Apr 19 Javascript
react系列从零开始_简单谈谈react
Jul 06 Javascript
如何测量vue应用运行时的性能
Jun 21 Javascript
js实现文章目录索引导航(table of content)
May 10 Javascript
Postman无法正常返回结果问题解决
Aug 28 Javascript
Vue开发中常见的套路和技巧总结
Nov 24 Vue.js
如何获取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
CURL的学习和应用(附多线程实现)
2013/06/03 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
基于jquery实现图片广告轮换效果代码
2011/07/07 Javascript
js实现数组去重方法及效率?Ρ? target=
2017/02/14 Javascript
基于JavaScript实现活动倒计时效果
2017/04/20 Javascript
vue中将网页打印成pdf实例代码
2017/06/15 Javascript
详解webpack 多入口配置
2017/06/16 Javascript
React如何将组件渲染到指定DOM节点详解
2017/09/08 Javascript
spirngmvc js传递复杂json参数到controller的实例
2018/03/29 Javascript
vue双向数据绑定知识点总结
2018/04/18 Javascript
详解vue组件基础
2018/05/04 Javascript
vue.js多页面开发环境搭建过程
2019/04/24 Javascript
优雅的使用javascript递归画一棵结构树示例代码
2019/09/22 Javascript
Vuex中的Mutations的具体使用方法
2020/06/01 Javascript
JS+canvas五子棋人机对战实现步骤详解
2020/06/04 Javascript
python计算圆周长、面积、球体体积并画出圆
2014/04/08 Python
python实现发送和获取手机短信验证码
2016/01/15 Python
Python提取Linux内核源代码的目录结构实现方法
2016/06/24 Python
Python字符串处理实现单词反转
2017/06/14 Python
Python导入模块时遇到的错误分析
2017/08/30 Python
python如何读写json数据
2018/03/21 Python
flask框架中勾子函数的使用详解
2018/08/01 Python
在python中pandas读文件,有中文字符的方法
2018/12/12 Python
dpn网络的pytorch实现方式
2020/01/14 Python
基于pandas向csv添加新的行和列
2020/05/25 Python
用css3实现转换过渡和动画效果
2020/03/13 HTML / CSS
Html5写一个简单的俄罗斯方块小游戏
2019/12/03 HTML / CSS
Sisley法国希思黎美国官方网站:享誉全球的奢华植物美容品牌
2020/06/27 全球购物
招商业务员岗位职责
2013/12/16 职场文书
高中生的自我鉴定范文
2014/01/24 职场文书
春季运动会广播稿大全
2014/02/19 职场文书
工程索赔意向书
2014/08/30 职场文书
2014党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
嘉宾邀请函
2015/01/31 职场文书
财务会计岗位职责
2015/02/03 职场文书
财务人员入职担保书
2015/09/22 职场文书