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 相关文章推荐
Prototype RegExp对象 学习
Jul 19 Javascript
将字符串中由空格隔开的每个单词首字母大写
Apr 06 Javascript
JavaScript运动减速效果实例分析
Aug 04 Javascript
jQuery实现的简单拖拽功能示例
Sep 13 Javascript
基于JS实现弹出一个隐藏的div窗口body页面变成灰色并且不可被编辑
Dec 14 Javascript
react.js使用webpack搭配环境的入门教程
Aug 14 Javascript
JavaScript 保护变量不被随意修改的实现代码
Sep 27 Javascript
vue修改对象的属性值后页面不重新渲染的实例
Aug 09 Javascript
JavaScript继承的特性与实践应用深入详解
Dec 30 Javascript
微信小程序的mpvue框架快速上手指南
May 15 Javascript
vue中axios的二次封装实例讲解
Oct 14 Javascript
Electron实现应用打包、自动升级过程解析
Jul 07 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
ThinkPHP中自定义目录结构的设置方法
2014/08/15 PHP
PHP.ini安全配置检测工具pcc简单介绍
2015/07/02 PHP
PHP可变函数学习小结
2015/11/29 PHP
PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间
2016/05/06 PHP
PHP开发实现快递查询功能详解
2019/04/08 PHP
laravel框架的安装与路由实例分析
2019/10/11 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
jquery 插件学习(一)
2012/08/06 Javascript
文本框回车提交与禁止提交示例
2013/09/27 Javascript
jquery实现的鼠标拖动排序Li或Table
2014/05/04 Javascript
详解AngularJS验证、过滤器、指令
2017/01/04 Javascript
jQuery代码实现实时获取时间
2017/01/29 Javascript
JS设置手机验证码60s等待实现代码
2017/06/14 Javascript
AngularJS中控制器函数的定义与使用方法示例
2017/10/10 Javascript
如何编写一个d.ts文件的步骤详解
2018/04/13 Javascript
JS正则表达式常见用法实例详解
2018/06/19 Javascript
layer.open回调获取弹出层参数的实现方法
2019/09/10 Javascript
vue-amap根据地址回显地图并mark的操作
2020/11/03 Javascript
[00:43]TI7不朽珍藏III——幽鬼不朽展示
2017/07/15 DOTA
Python标准库之循环器(itertools)介绍
2014/11/25 Python
python爬虫自动创建文件夹的功能
2018/08/01 Python
Python视频编辑库MoviePy的使用
2020/04/01 Python
Python实现爬取并分析电商评论
2020/06/19 Python
中国专业的音频分享平台:喜马拉雅
2019/05/24 全球购物
沙特阿拉伯家用电器和电子产品购物网站:Sheta and Saif
2020/04/03 全球购物
N:Philanthropy官网:美国洛杉矶基础款服装
2020/06/09 全球购物
应届生如何写自荐信
2014/01/05 职场文书
餐厅楼面部长岗位职责范文
2014/02/16 职场文书
高中军训感言500字
2014/02/24 职场文书
宣传普通话标语
2014/06/27 职场文书
党支部创先争优活动总结
2014/08/28 职场文书
万能检讨书开头与结尾怎么写
2015/02/17 职场文书
门店店长岗位职责
2015/04/14 职场文书
2015年暑期社会实践方案
2015/07/14 职场文书
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android
Python获取字典中某个key的value
2022/04/13 Python