JavaScript中timer是如何工作的

作为入门者来说,了解JavaScript中timer的工作方式是很重要的。通常它们的表现行为并不是那么地直观,这是因为它们都处在单线程中。让我们先来看看三个用来出创建和操作timer的函数。

var id = setTimeout(fn, delay);

初始化这个timer,然后这个timer将会在delay延时后调用这个函数fn。这个函数将返回一个唯一的ID,可以通过这个ID来取消timer。

var id = setInterval(fn, delay);

与setTimeout类似,不过它会持续调用函数fn(每隔delay毫秒),直到timer被取消。

clearTimeout(id);
clertInterval(id);

接受一个timer的ID,并停止timer的回调事件。

为了理解timer内部工作原理,我们还需要知道一个重要的概念:timer的延时是不准确的。由于浏览器中的JavaScript在单线程中运行,因此异步事件(如mouse click以及timer)只有在执行期空闲的时候才运行。这个用图表最能解释清楚了,参看下图:

这个图标中有大量的信息可以挖掘,但是完全理解它将使我们对JavaScript中异步事件执行原理有个更深的认识。这是一张一维图:数值方向为时间,单位毫秒。蓝色的框表示正在执行的JavaScript片段。举个例子,第一块JavaScript大约执行了18ms,鼠标点击则执行了11ms,以此类推。

由于JavaScript在同一时间只能执行一段代码(由单线程的本质决定),因此每个代码块都会“阻塞”其他异步事件。这意味着当异步事件发生时(比如鼠标点击、timer触发或者XMLHttpRequest完成),将进入事件队列等待执行(队列的实现方式因浏览器而异,这里只讨论简化的情况)。

从第一段JavaScript代码块开始,有两个timer被初始化了:一个10ms的setTimeout和一个10ms的setInterval。其实在第一段代码块执行完之前timer就已经触发了。注意,无论如何它都不会立即执行(由于单线程原因,它无法那样做)。相反,这个延时执行的函数进入队列等待下次空闲的时候执行。

此外,第一段代码块中鼠标点击事件也发生了。因此和异步事件相关联的回调函数也不能立即执行,像最初的timer一样,也要进入队列等待执行。

最初的代码块执行完以后,浏览器问了这样一个问题:谁在等待执行?这个例子中,鼠标点击事件和timer回调函数都处于等待中。浏览器挑了鼠标点击事件,然后立即执行它。而timer将继续等待下次执行。

注意当鼠标点击事件执行过程中时,第一次的interval的回调也触发了。和timer一样,它的事件也将进入队列等待执行。然后,当interval再次触发的时候(此时timer正在执行),这次它的事件将被丢弃。如果你在一大块代码执行时,把所有的interval的回调事件排入队列,其结果是在上述代码执行完以后,一推的interval事件将毫无间隔地执行。而浏览器更趋向于等待,以确保interval事件进入队列时没有其他的interval事件。

事实上,从这个例子中可以看出:当第三个interval触发的时候,interval自身正在执行。这告诉我们一个重要的事实:interval不管当前执行的是什么,都会进入队列,即使这样意味着回调函数之间的时间就不准确了。

最后,当第二个interval事件执行完以后,将没有任何代码留给JavaScript引擎执行。这意味着现在浏览器将等待新的异步事件触发。于是在50ms的时候,interval再一次触发。这一次,没有什么阻塞它的执行,它就立即触发了。

让我们看一个例子来更好的阐述setTimeout和setInterval之间的区别。

setTimeout(function(){
    /*Some long block of code */
    setTimeout(argument.callee, 10)
}, 10);

setInterval(function(){
    /*Some long block of code */
}, 10)

咋看一下,这两段代码的功能似乎是一样的,但实际上并非如此。尤其是setTimeout这段代码,在前一个回调函数执行完以后,都至少会有10ms的延时(可能会多,但绝不会少)。然而,setInterval的代码则总是每10ms的时候尝试执行回调,无论上一次回调什么时候执行的。

重述下学到的知识。

  • JavaScript引擎只有一个线程,这使得异步事件必须排入队列等待执行
  • setTimeout和setInterval在执行异步代码上有着本质的区别
  • 如果timer在将要执行的时候被阻塞,它将等待下一个时机
  • 如果interval执行的时候很长(比指定的时间长),那么它们将连续地执行而没有延时。

原文:jQuery之父John Resig的Blog

http://ejohn.org/blog/how-javascript-timers-work/

JavaScript中timer是如何工作的

时间: 2024-10-18 19:35:44

JavaScript中timer是如何工作的的相关文章

JavaScript 中 this 是如何工作的 ?

先来看看这个题目: var x = 0; var foo = { x:1, bar:{ x:2, baz: function () { console.log(this.x) } } } var a = foo.bar.baz foo.bar.baz() // 2 a() //0 this 永远指向函数运行时所在的对象,而不是函数创建时所在的对象 匿名函数和不处于任何对象中的函数,This指向window call, apply, with指的This是谁就是谁. 普通函数调用,函数被谁调用,T

[ Javascript ] JavaScript中的定时器(Timer) 是如何工作的!

作为入门者来说,了解JavaScript中timer的工作方式是很重要的.通常它们的表现行为并不是那么地直观,而这是因为它们都处在一个单一线程中.让我们先来看一看三个用来创建以及操作timer的函数. var id = setTimeout(fn, delay); - 初始化一个单一的timer,这个timer将会在一定延时后去调用指定的函数.这个函数(setTimeout)将返回一个唯一的ID,我们可以通过这个ID来取消timer. var id = setInterval(fn, delay

【JavaScript】JavaScript中的Timer是怎么工作的( setTimeout,setInterval)

原文(http://www.yeeyan.org/articles/view/luosheng/24380) 作为入门者来说,了解JavaScript中timer的工作方式是很重要的.通常它们的表现行为并不是那么地直观,而这是因为它们都处在一个单一线程中.让我们先来看一看三个用来创建以及操作timer的函数. var id = setTimeout(fn, delay); - 初始化一个单一的timer,这个timer将会在一定延时后去调用指定的函数.这个函数(setTimeout)将返回一个唯

【译】在JavaScript中{}+{}的结果是什么?

原文链接:What is {} + {} in JavaScript? 最近,Gary Bernhardt在一个名为'Wat'的闪电演讲中提到了一些有趣的JavaScript技巧.当你把一个object和一个object或者和一个数组相加时,会获得意想不到的结果.这篇文章将会对这些结果做解释. 在JavaScript中,对于+的普通规则很简单:你可以把数字和字符串相加,结果将会被转换成他们中的一种类型.为了理解这种类型转换时如何工作的,我首先需要了解一些其他东西.无论何时引用一个段落,它都引自E

JavaScript中this的工作原理以及注意事项

在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this 所在的位置来理解它,情况大概可以分为3种: 1.在函数中:this 通常是一个隐含的参数. 2.在函数外(顶级作用域中):在浏览器中this 指的是全局对象:在Node.js中指的是模块(module)的导出(exports). 3.传递到eval()中的字符串:如果eval()是被直接调用的,th

javascript中闭包的工作原理

一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话通俗的来说就是:JavaScript中所有的function都是一个闭包.不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”.看下面这段代码: 1 2 3 4 5 6 7 function a() { var i = 0; function b() { ale

javascript中事件timer

<!DOCTYPE html> <html> <head> <title>javascript中的事件处理</title> <meta charset="UTF-8"> <script type="text/javascript"> var timeId; function cd(){ //在3秒之后执行bigger函数setTimeOut的意思就是间隔一段时间来执行某个函数 //s

学习JavaScript中的异步Generator

本文和大家分享的主要是javascript中异步Generator相关内容,一起来看看吧,希望对大家学习javascript 有所帮助. 异步的generators和异步iteration已经到来 ! 这是错误的, 它们现在还在 阶段 3 ,这表示他们很有可能在JavaScript未来的一个版本中发布. 在他们发布之前,你可以通过 Babel 来在你的项目中使用还在阶段3的建议内容. 网站基本上还是一些分散运行的应用,因为任何在语言上的修改都会造成永久的影响,所以所有的未来的版本都需要向后兼容.

JavaScript中常见的十五种设计模式

在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”. 在JavaScript中并没有类这种概念,JS中的函数属于一等对象,在JS中定义一个对象非常简单(var obj = {}),而基于JS中闭包与弱类型等特性,在实现一些设计模式的方式上与众不同. 本文基于<JavaScript设计模式与开发实践>一书,用一些例子总结一下JS常见的设计模式与实现方法.文章略长,自备瓜子板凳~ 设计原则 单一职责原则(SRP) 一个对象或方法只做一件事情.如果一个方法承担了过多的职责,那么在