JavaScript定时器的工作原理(翻译)
JavaScript定时器的工作原理(翻译)
标签(空格分隔): JavaScript定时器
最近在看ajax原理的时候,看到了一篇国外的文章,讲解了JavaScript定时器的工作原理,帮助我很好的理解了js的单线程工作模式。在这里翻译一下供大家参考,原文地址.
翻译正文
从根本上讲,了解JavaScript定时器的工作原理非常重要。通常 js的单线程表现的。让我们首先看一下可以构造和操作定时器的三个函数。
- 启动单个定时器,在延迟后调用指定的功能。该函数返回一个唯一的ID,该Id可以用于取消定时器
var id = setTimeout(fn, delay);
- 类似setTimeout但不断地调用函数(每次都有延迟),直到它被取消,类似于定时任务。同上也返回唯一ID用于取消定时器
var id = setInterval(fn, delay);
- 接受计时器ID(由上述任一功能返回)并停止触发计时器回调。
clearInterval(id);
clearTimeout(id);
为了理解定时器的内部工作原理,我们需要探索一个重要的概念:定时器延迟并不能保证准确。由于浏览器中的所有JavaScript都在单个线程上执行,因此异步事件(例如鼠标单击和计时器)仅在可被执行时运行。使用图表可以最好地证明这一点,如下所示:
这个图中有很多信息需要理解,完全理解它会让你更好地了解异步JavaScript执行的工作方式。这个图是一维的:垂直方向,我们有(挂钟)时间(译注:左侧的时间刻度),以毫秒为单位。蓝色框表示正在执行的JavaScript部分。例如,第一个JavaScript块执行大约18ms,鼠标单击块大约需要11ms,依此类推。
由于JavaScript一次只能执行一段代码(由其单线程性质决定),因此每个代码块都“阻塞”其他异步事件的进度。这意味着当异步事件发生时(如鼠标单击,计时器触发或XMLHttpRequest完成),它会先排队等待(译注:可以理解为一个队列)以后执行(这种排队实际发生的方式因浏览器到浏览器而异,这里是做了一个简单说明)。
首先,在JavaScript的第一个块中,启动两个定时器:10ms setTimeout和10ms setInterval。由于计时器启动的位置和时间,它实际上在我们实际完成第一个代码块之前触发。但请注意,它不会立即执行(由于线程,它无法执行此操作)而是进入排队队列,以便在下一个可用时刻执行。
此外,在第一个JavaScript块中,我们看到鼠标单击。鼠标点击事件关联的JavaScript回调(我们永远不知道用户何时执行一个操作,因此它被认为是异步的)无法立即执行,因此,与初始计时器一样,它排队等待稍后执行。
在JavaScript的初始块完成后,执行浏览器会立即询问:队列中有什么等待执行的任务?在这种情况下,鼠标单击处理程序和计时器回调都在等待。然后浏览器选择一个(鼠标单击回调)并立即执行它。计时器将等到下一个时间被从队列中取出执行。
请注意,当鼠标单击处理程序执行时,执行第一个间隔回调。与计时器一样,它的处理程序进入排队等待以后执行。但是,请注意,当再次触发间隔时(在执行timer程序时),此时Interval的间隔回调被丢弃(译者注:这里不是很理解,欢迎留言交流指教。是否是因为已经有interval在排队?)。如果要在执行大块代码时调用间隔回调,间隔回调将连续加入到任务队列中,它们之间没有延迟。浏览器往往只是简单的去队列中取任务直到队列中没有其他任务。
事实上,我们可以看到,当间隔本身正在执行时,第三个间隔回调会触发。这向我们展示了一个重要的事实:Intervals不关心当前正在执行的内容,它们会不加选择地排队。
最后,在第二个间隔回调完成执行后,我们可以看到JavaScript引擎没有任何任务可以执行。这意味着浏览器现在等待发生新的异步事件。当间隔再次触发时,在50ms的位置。但是,这一次,没有任何程序正在执行,所以它会立即被触发。
让我们看一个例子,以更好地说明setTimeout和setInterval之间的差异。
setTimeout(function(){
/* Some long block of code... */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/* Some long block of code... */
}, 10);
这两段代码乍一看似乎在功能上等同,但它们不是。值得注意的是,setTimeout代码在前一次回调执行后总是至少有10ms的延迟(它可能最终会更多,但绝不会少于10ms),而setInterval在这段长代码执行期间它都会尝试每10ms执行一次回调(译者注:可理解为在这段长代码执行期间,会每10ms添加一个任务进队列,中间无间隔)。
我们在这里学到了很多,让我们回顾一下:
JavaScript引擎只有一个线程,迫使异步事件排队等待执行。
setTimeout并且setInterval它们在执行异步代码方面有着根本的不同。
如果计时器被阻止立即执行,它将被延迟到下一个可能的执行点(这将超过所需的延迟)。
如果setInterval中回调程序执行时间足够长(超过指定的延迟),则间隔可以无延迟地执行(译者注:因为在一个回调没有运行完的时候就会再加入一个回调)。
所有这些都是用来了解JavaScript引擎的工作原理的非常重要的知识,尤其是发生的大量异步事件的时候,为构建高级应用程序代码奠定了基础。
JavaScript定时器的工作原理(翻译)的更多相关文章
- 我们应该如何去了解JavaScript引擎的工作原理
“读了你的几篇关于JS(变量对象.作用域.上下文.执行代码)的文章,我个人觉得有点抽象,难以深刻理解.我想请教下通过什么途径能够深入点的了解javascript解析引擎在执行代码前后是怎么工作的,ec ...
- 【转】我们应该如何去了解JavaScript引擎的工作原理
原文地址:http://www.nowamagic.net/librarys/veda/detail/1579 昨天收到一封来自深圳的一位前端童鞋的邮件,邮件内容如下(很抱歉,未经过他的允许,公开邮件 ...
- JavaScript原型继承工作原理
原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...
- js:我们应该如何去了解JavaScript引擎的工作原理(转)
http://www.nowamagic.net/librarys/veda/detail/1579 昨天收到一封来自深圳的一位前端童鞋的邮件,邮件内容如下(很抱歉,未经过他的允许,公开邮件内容,不过 ...
- 浏览器中“JavaScript解析器”工作原理
浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤: 1.“找一些东西”: v ...
- JavaScript的单线程性质以及定时器的工作原理
前些日子还在网上争论过js动画用setTimeout还是setInterval,个人偏向于setTimeout,当动画中牵扯到ajax时用setInterval会有时间偏差,出现一些问题即使用clea ...
- JavaScript定时器实现的原理分析
原文链接:http://www.cnblogs.com/st-leslie/p/6082450.html 一.储备知识 在我们在项目中一般会遇见过这样的两种定时器,第一种是setTimeOut,第二种 ...
- javascript this 的工作原理
JavaScript 有一套完全不同于其它语言的对 this 的处理机制. 在五种不同的情况下 ,this 指向的各不相同. 1.全局范围内 当在全部范围内使用 this,它将会指向全局对象. 2.函 ...
- JavaScript引擎的工作原理
http://my.oschina.net/fuckBAT/blog/318355?fromerr=jK6wCh1p#OSC_h4_4
随机推荐
- 几点建议,让Redis在你的系统中发挥更大作用
Redis在很多方面与其他数据库解决方案不同:它使用内存提供主存储支持,而仅使用硬盘做持久性的存储:它的数据模型非常独特,用的是单线程.另一个大区别在于,你可以在开发环境中使用Redis的功能,但却不 ...
- 常系数线性递推的第n项及前n项和 (Fibonacci数列,矩阵)
(一)Fibonacci数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的第n项的快速求法(不考虑高精度). 解法: 考虑1×2的矩阵[f[n-2],f[n-1]].根据fibon ...
- SSM 后台封装的有值, 到前台打印的时候没有值
原因: 实体类中的getting setting 方法没有配置,导致封装json 数据的时候没有封装进去
- 【代码笔记】iOS-字符串替换回车和换行
一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, ...
- Hystrix 框架
雪崩效应的产生原因:当一个服务突然受到高并发的请求,tomcat服务器承受不了的情况下会产生服务堆积,可能导致其他的服务也不可用. 服务保护:当服务产生堆积的时候,对服务实现保护功能. 服务隔离:每个 ...
- SSL certificate problem: unable to get local issuer certificate 的解决方法
今天在进行微信开发获取微信Access_Token时,使用到了php的curl库, 在敲完代码后获取token失败,经过各种排查错误,到了下面这一步 SSL certificate problem: ...
- 高性能JavaScript(快速响应的用户界面)
浏览器UI线程 用于执行JavaScript代码和更新界面的进程被称为 “浏览器UI线程” . UI线程的工作基于一个简单的队列系统,任务会被保存到队列中直到线程空闲,一旦空闲队列就被重新提取出来运行 ...
- 【webpack】webpack.base.conf.js基础配置
var path = require('path') // node路径模块 var utils = require('./utils') // 对vue-loader对于css预编译一些提取的工具模 ...
- objc与鸭子对象(上)
这是<objc与鸭子对象>的上半部分,<objc与鸭子对象(下)>中介绍了鸭子类型的进阶用法.依赖注入以及demo. 我是前言 鸭子类型(Duck Type)即:“当看到一只鸟 ...
- Android Studio离线打包5+SDK
dcloud官网下载最新版5+SDK 解压后,Android Studio导入HBuilder-Hello,选择From eclispe 修改assets/data/dcloud_control.xm ...