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定时器的工作原理(翻译)的更多相关文章

  1. 我们应该如何去了解JavaScript引擎的工作原理

    “读了你的几篇关于JS(变量对象.作用域.上下文.执行代码)的文章,我个人觉得有点抽象,难以深刻理解.我想请教下通过什么途径能够深入点的了解javascript解析引擎在执行代码前后是怎么工作的,ec ...

  2. 【转】我们应该如何去了解JavaScript引擎的工作原理

    原文地址:http://www.nowamagic.net/librarys/veda/detail/1579 昨天收到一封来自深圳的一位前端童鞋的邮件,邮件内容如下(很抱歉,未经过他的允许,公开邮件 ...

  3. JavaScript原型继承工作原理

    原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...

  4. js:我们应该如何去了解JavaScript引擎的工作原理(转)

    http://www.nowamagic.net/librarys/veda/detail/1579 昨天收到一封来自深圳的一位前端童鞋的邮件,邮件内容如下(很抱歉,未经过他的允许,公开邮件内容,不过 ...

  5. 浏览器中“JavaScript解析器”工作原理

    浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤: 1.“找一些东西”: v ...

  6. JavaScript的单线程性质以及定时器的工作原理

    前些日子还在网上争论过js动画用setTimeout还是setInterval,个人偏向于setTimeout,当动画中牵扯到ajax时用setInterval会有时间偏差,出现一些问题即使用clea ...

  7. JavaScript定时器实现的原理分析

    原文链接:http://www.cnblogs.com/st-leslie/p/6082450.html 一.储备知识 在我们在项目中一般会遇见过这样的两种定时器,第一种是setTimeOut,第二种 ...

  8. javascript this 的工作原理

    JavaScript 有一套完全不同于其它语言的对 this 的处理机制. 在五种不同的情况下 ,this 指向的各不相同. 1.全局范围内 当在全部范围内使用 this,它将会指向全局对象. 2.函 ...

  9. JavaScript引擎的工作原理

    http://my.oschina.net/fuckBAT/blog/318355?fromerr=jK6wCh1p#OSC_h4_4

随机推荐

  1. 【15】模板方法模式(Template Method)

    一.引言 提到模板,大家肯定不免想到生活中的“简历模板”.“论文模板”.“Word中模版文件”等.在现实生活中,模板的概念就是——有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它.例如简 ...

  2. 简单的redis缓存操作(get、put)

    简单的redis缓存操作(get.put) 本文介绍简单的redis缓存操作,包括引入jedisjar包.配置redis.RedisDao需要的一些工具.向redis中放数据(put).从redis中 ...

  3. zsh: command not found: pip 解决方法

    出现zsh: command not found: xxx解决方法: 把 bash shell 中.bash_profile 全部环境变量加入zsh shell里就好 step1: Term执行 op ...

  4. 集合框架四(Map)

    Map的主要实现类: --HashMap:Map的主要实现类(掌握) --LinkedHashMap:使用链表维护添加进Map中的顺序,遍历时按添加时的顺序遍历 --TreeMap:按照添加进Map中 ...

  5. POJO、JAVABEAN、*O、EJB

    POJO: 全称:Plain Old Java Object 解释:纯洁老式的java对象.从任何类继承.也没有实现任何接口,更没有被其它框架侵入的java对象 理解:通常我们常说的实体类 BEAN: ...

  6. <Android开源库> PagerSlidingTabStrip从头到脚

    简介 PagerSlidingTabStrip,是我个人经常使用到的一个和ViewPager配合的页面指示器,可以满足开发过程中常用的需求,如类似于今日头条的首页新闻内容导航栏等等,之前自己开发的Ju ...

  7. 浅析ARM公司在物联网领域的战略布局

    From: http://www.cnblogs.com/yefanqiu/p/3447769.html 浅析ARM公司在物联网领域的战略布局 随着ARM芯片的出货量越来越多,自信满满的ARM公司统一 ...

  8. Difference between nn.softmax & softmax_cross_entropy_with_logits & softmax_cross_entropy_with_logits_v2

    nn.softmax 和 softmax_cross_entropy_with_logits 和 softmax_cross_entropy_with_logits_v2 的区别   You have ...

  9. react native进阶

    一.前沿||潜心修心,学无止尽.生活如此,coding亦然.本人鸟窝,一只正在求职的鸟.联系我可以直接微信:jkxx123321 二.项目总结 **||**文章参考资料:1.  http://blog ...

  10. python 计时器

    今天做自动化界面工具的时候需要用到计时器,查阅了一下,发现以下的这位博友写的很简洁方便且实用 https://blog.csdn.net/qfxx_CSDN/article/details/81412 ...