setTimeout和setInterval的深入理解
大概半年前发表过一篇关于setTimeout和setInterval的文章,但是现在回去仔细一看发现其实存在很多不足以及错误。事实上,setTimeout和setInterval并没有我们字面上理解的那么简单。要真正掌握并理解这两个方法,还得从javascript的单线程机制说起。
【开门见山】setTimeout和setInterval是如何工作的呢?
我们知道,js是单线程执行的。所以其实setTimeout和setInterval所谓的“异步调用”事实上是通过将代码段插入到代码的执行队列中实现的。
而如何计算插入的时间点呢?自然是要用到我们所说的timer,也就是计时器。当执行setTimeout和setInterval的时候,timer会根据你设定的时间“准确”地找到代码的插入点。当队列“正常”地执行到插入点时,就触发timer callback,也就是我们设定的回调函数:
/*
here is some codes
*/ www.jbxue.com
setTimeout(function() {alert('ok!')},1000);
}
上面这个例子就是我们通常的用法,应该容易理解。可是,timer真的能那么准确么?代码队列的执行真的能那么正常么?
【斩草除根】重新认识所谓的“异步”
刚刚已经知道,事实上setTimeout和setInterval只是简简单单地通过插入代码到代码队列来实现代码的延迟执行(或者说异步执行)。但是事实上所谓的异步只是一个假象——它同样运行在一个线程上!
那么问题就来了,要是在代码插入点前的代码执行时间超过了传入setTimeout或setInterval的设定时间会怎样呢?让我们来看看这段代码:
setTimeout(function(){alert('can you see me?');},1000);
while(true) {}
}
你觉得这段代码的执行结果是什么呢?答案是,alert永远不会出现。
这是为什么呢?因为,while这段代码没有执行完,插入在后面的代码便永远不会执行。
综上所述,其实JS终归是单线程产物。无论如何“异步”都不可能突破单线程这个障碍。所以许多的“异步调用”(包括Ajax)事实上也只是“伪异步”而已。只要理解了这么一个概念,也许理解setTimeout和setInterval也就不难了。
setTimeout和setInterval的深入理解的更多相关文章
- JavaScript的setTimeout和setInterval的深入理解
发表过一片博客<跟着我用JavaScript写计时器>,比较基础.....有网友说应该写一下setTimeout的原理和机制,嗯,今天就来写一下吧: 直奔主题:setTimeout和set ...
- setTimeout和setInterval定时器使用详解测试
var len=4; while(len--){ var time=setTimeout(function(){ console.log(len); },0); console.log(time); ...
- 深入理解定时器系列第一篇——理解setTimeout和setInterval
× 目录 [1]setTimeout [2]setInterval [3]运行机制[4]作用[5]应用 前面的话 很长时间以来,定时器一直是javascript动画的核心技术.但是,关于定时器,人们通 ...
- 原生js轮播以及setTimeout和setInterval的理解
下面这个代码是从一个群下载下来的,为了帮助自己理解和学习现在贴出来,与初学者共勉. <!DOCTYPE html> <html> <head> <meta c ...
- 深入理解setTimeout和setinterval
以前一直以为这两个函数就是简单了认为类似thread一样的东西, 认为会在一个时间片内, 并发的执行调用的函数, 似乎很好很强大, 但其实并不是如此, 实际的情况是javascript都是以单线程的方 ...
- 理解setTimeout和setInterval
setTimeout和setInterval,这两个js函数都是用来定时执行.setTimeout执行一次,setInterval执行多次. 问题出现在今天,使用setInterval是,设置执行速度 ...
- setTimeout,setInterval原理
function a() { setTimeout(function(){alert(1)},0); alert(2); } a(); 和其他的编程语言一样,Javascript中的函数调用也是通过堆 ...
- setTimeout和setInterval的注意事项
精准问题 setTimeout的问题在于它并不是精准的,例如使用setTimeout设定一个任务在10ms后执行,但是在9ms后,有一个任务占用了5ms的cpu时间片,再次轮到定时器执行时,时间已经过 ...
- setTimeout和setInterval的区别以及如何写出效率高的倒计时
1.setTimeout和setInterval都属于js中的定时器,可以规定延迟时间再执行某个操作,不同的是setTimeout在规定时间后执行完某个操作就停止了,而setInterval则可以一直 ...
随机推荐
- Quartz 多个触发器
http://www.oschina.net/code/snippet_114990_4440 最近项目中要做个定时生成静态html文件东东,7点到19点每5分钟生成一次,其他时间1小时生成一次,刚开 ...
- C# 基础知识 protected 关键字
using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace Console ...
- ios调打电话代码
// 定义点击拨号按钮时的操作 - (void)callAction{ NSString *number = @"";// 此处读入电话号码 // NSString *num = ...
- DirectoryExists
判断文件夹是否存在 关键点 GetFileAttributes The GetFileAttributes function retrieves attributes for a specified ...
- Linux环境进程间通信
http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html http://bbs.chinaunix.net/forum.ph ...
- My安装Eclipse三种方法插件
Eclipse它是一个开源项目,但非常需要手动集成插件,MyEclipse在Eclipse插件.但非常多时候MyEclipse相同须要再次安装插件,插件安装有三种方法,以下以SVN为例.具体阐述. E ...
- cocos2d-x设计模式发掘之五:防御式编程模式
http://www.ityran.com/archives/2105 本文由子龙山人原创,泰然授权转载,转载请注明出处并通知子龙山人! 声明:防御式编程是提高程序代码质量的一种手段,它不能算是真正意 ...
- mysql脚本mysql_safe解释、mysql.sock文件、mysql_install_db
1.首先解释下,启动mysql时为何会调用mysql_safe脚本来启动mysql [root@localhost ~]# /etc/init.d/mysqld start 正在启动 mysqld: ...
- PHP + ajax 实现异步登录验证
login.html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...
- java.lang.NoClassDefFoundError: com.nostra13.universalimageloader.core.DisplayImageOptions$Builder
今天在使用Universal-image-loader开源插件的时候,一直出现了这么个错误.原因是在ADT22版本中导入jar包的方式不对. 正确的导入jar包方式: 在adt17的版本之后,导入第三 ...