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.jstree 增加节点的双击事件代码
Jul 27 Javascript
jQuery.get、jQuery.getJSON、jQuery.post无法返回JSON问题的解决方法
Jul 28 Javascript
jquer之ajaxQueue简单实现代码
Sep 15 Javascript
jquery 添加节点的几种方法介绍
Sep 04 Javascript
js中arguments,caller,callee,apply的用法小结
Jan 28 Javascript
jQuery实现动态表单验证时文本框抖动效果完整实例
Aug 21 Javascript
jquery实现图片放大镜功能
Nov 23 Javascript
jQuery Easyui Datagrid实现单行的上移下移及保存移动的结果
Aug 15 Javascript
轻松学习JavaScript函数中的 Rest 参数
May 30 Javascript
js中Function引用类型常见有用的方法和属性详解
Dec 11 Javascript
基于javascript canvas实现五子棋游戏
Jul 08 Javascript
js闭包和垃圾回收机制示例详解
Mar 01 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
IP138 IP地址查询小偷实现代码
2010/02/15 PHP
php session劫持和防范的方法
2013/11/12 PHP
如何使用Gitblog和Markdown建自己的博客
2015/07/31 PHP
Yii2针对游客、用户防范规则和限制的解决方法分析
2016/10/08 PHP
通过Unicode转义序列来加密,按你说的可以算是混淆吧
2007/05/06 Javascript
jquery插件之信息弹出框showInfoDialog(成功/错误/警告/通知/背景遮罩)
2013/01/09 Javascript
JS实现兼容性好,自动置顶的淘宝悬浮工具栏效果
2015/09/18 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
2016/01/18 Javascript
js类式继承与原型式继承详解
2016/04/07 Javascript
BootStrap入门教程(三)之响应式原理
2016/09/19 Javascript
详解简单易懂的 ES6 Iterators 指南和示例
2019/09/24 Javascript
jquery实现聊天机器人
2020/02/08 jQuery
Node.js API详解之 os模块用法实例分析
2020/05/06 Javascript
javascript递归函数定义和用法示例分析
2020/07/22 Javascript
vue等两个接口都返回结果再执行下一步的实例
2020/09/08 Javascript
python使用socket远程连接错误处理方法
2015/04/29 Python
python实现将一个数组逆序输出的方法
2018/06/25 Python
Python求两个圆的交点坐标或三个圆的交点坐标方法
2018/11/07 Python
对python插入数据库和生成插入sql的示例讲解
2018/11/14 Python
对DJango视图(views)和模版(templates)的使用详解
2019/07/17 Python
Django forms表单 select下拉框的传值实例
2019/07/19 Python
python中sort和sorted排序的实例方法
2019/08/26 Python
Python帮你识破双11的套路
2019/11/11 Python
Python 多进程、多线程效率对比
2020/11/19 Python
HTML5公共页面提取作为公用代码的方法
2020/06/30 HTML / CSS
GAZMAN官网:澳大利亚领先的男装品牌
2019/12/19 全球购物
智能室内花园:Click & Grow
2021/01/29 全球购物
教师个人的自我评价分享
2014/01/02 职场文书
办公室打字员岗位职责
2014/04/16 职场文书
员工考核评语大全
2014/04/26 职场文书
学校督导评估方案
2014/06/10 职场文书
加强作风建设工作总结
2014/10/23 职场文书
学校师德师风整改方案
2014/10/28 职场文书
css3实现背景图片半透明内容不透明的方法示例
2021/04/13 HTML / CSS
Python自动化之批量处理工作簿和工作表
2021/06/03 Python
springboot拦截器无法注入redisTemplate的解决方法
2021/06/27 Java/Android