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实现上传图片前的预览(TX的面试题)
Aug 20 Javascript
JavaScript人脸识别技术及脸部识别JavaScript类库Tracking.js
Sep 14 Javascript
javascript实现不同颜色Tab标签切换效果
Apr 27 Javascript
使用JavaScript触发过渡效果的方法
Jan 19 Javascript
从零开始学习Node.js系列教程一:http get和post用法分析
Apr 13 Javascript
jquery实现下拉菜单的手风琴效果
Jul 23 jQuery
完美实现js拖拽效果 return false用法详解
Jul 28 Javascript
VUE 实现滚动监听 导航栏置顶的方法
Sep 11 Javascript
angular学习之动态创建表单的方法
Dec 07 Javascript
jquery实现下载图片功能
Jul 18 jQuery
vue 实现tab切换保持数据状态
Jul 21 Javascript
Vue实现简单的拖拽效果
Aug 25 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 增加了对 .ZIP 文件的读取功能
2006/10/09 PHP
PHP CURL模拟GET及POST函数代码
2010/04/25 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
javascript基本语法分析说明
2008/06/15 Javascript
extjs关于treePanel+chekBox全部选中以及清空选中问题探讨
2013/04/02 Javascript
用js实现table单元格高宽调整,兼容合并单元格(兼容IE6、7、8、FF)实例
2013/06/25 Javascript
简介JavaScript中Math.LOG10E属性的使用
2015/06/14 Javascript
JavaScript每天定时更换皮肤样式的方法
2015/07/01 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
js仿QQ中对联系人向左滑动、滑出删除按钮的操作
2016/04/07 Javascript
JS实现图文并茂的tab选项卡效果示例【附demo源码下载】
2016/09/21 Javascript
jQuery EasyUI tree增加搜索功能的实现方法
2017/04/27 jQuery
layui导航栏实现代码
2017/05/19 Javascript
vue 实现搜索的结果页面支持全选与取消全选功能
2019/05/10 Javascript
js实现抽奖的两种方法
2020/03/19 Javascript
[02:17]《辉夜杯》TRG战队巡礼
2015/10/26 DOTA
python根据开头和结尾字符串获取中间字符串的方法
2015/03/26 Python
在Python的Flask中使用WTForms表单框架的基础教程
2016/06/07 Python
使用python 打开文件并做匹配处理的实例
2019/01/02 Python
python 通过类中一个方法获取另一个方法变量的实例
2019/01/22 Python
浅谈python编译pyc工程--导包问题解决
2019/03/20 Python
如何通过python画loss曲线的方法
2019/06/26 Python
pytorch中tensor.expand()和tensor.expand_as()函数详解
2019/12/27 Python
Python 实现将数组/矩阵转换成Image类
2020/01/09 Python
关于Python 中的时间处理包datetime和arrow的方法详解
2020/03/19 Python
Django日志及中间件模块应用案例
2020/09/10 Python
python利用后缀表达式实现计算器功能
2021/02/22 Python
详解CSS中iconfont的使用
2015/08/04 HTML / CSS
CSS3实现淘宝留白的方法
2020/06/05 HTML / CSS
生产经理的自我评价分享
2013/11/07 职场文书
安全生产实施方案
2014/02/23 职场文书
网络管理员岗位职责
2014/03/17 职场文书
2014年精神文明建设工作总结
2014/11/19 职场文书
担保书范本
2015/01/20 职场文书
商场广播稿范文
2015/08/19 职场文书
教师信息技术学习心得体会
2016/01/21 职场文书