`
liss
  • 浏览: 844287 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

JavaScript中的Timer是怎么工作的

阅读更多

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

var id = setTimeout(fn, delay);——初始化一个单一的timer,这个timer将会在一定延时后去调用指定的函数。这个函数(setTimeout)将返回一个唯一的ID,我们可以通过这个ID来取消timer。 
var id = setInterval(fn, delay);——与setTimeout类似,只不过它会持续地调用指定的函数(每次都有一个延时),直到timer被取消为止。 
clearInterval(id);clearTimeout(id);——接受一个timer的ID(由上述的两个函数返回的),并且停止timer的回调事件。 
要搞明白timer在内部是怎么工作的,我们还需要知道一个很重要的概念:timer的延时并不是每次都能如你所愿的。由于在同一个浏览器中所有的JavaScript都只在单一线程中执行,那些异步的事件(比如说鼠标点击,或者timer)只在执行期出现空闲的时候才会运行。这个用图最能表示清楚了,请参见下图:


在这个示例中有很多信息可以挖掘,但是完全理解了之后你将会更清楚地认识到异步的JavaScript是怎么执行的。这是个一维的图:竖直方向上的是(挂钟式)时间,单位为毫秒。蓝色的框表示正在执行的JavaScript片段。举例来说,第一块JavaScript执行了约18ms,而鼠标点击则执行了约11ms,以此类推。

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

刚开始,在第一个JavaScript块中,有两个timer被初始化了:一个10ms的setTimeout和一个是10ms的setInterval。由于timer(这里的timer指setTimeout中的timer,而下文中的interval则指setInvertal中的timer)开始的时间,实际上它在第一个代码块结束前就已经触发了。然而请注意,它并不会马上执行(事实上由于单线程的存在,它也无法做到马上执行)。相反的,这个被延期执行的函数进入队列中,等待在空闲的时候被执行。

另外,在第一个JavaScript块中,我们看到一个鼠标点击事件也发生了。而与这个异步事件(我们不知道用户什么时候会去执行一个动作,因此将其认为是一个异步动作)相关的JavaScript回调函数也无法立马执行,正如timer一样,它也进行到队列中等待被执行。

当第一个JavaScript块被执行完之后,浏览器问了一个问题:有正在等待被执行的代码吗?在这个例子中,鼠标点击事件和time事件都正在队列中等待。于是浏览器选了一个(鼠标点击事件),然后马上执行它。而timer只能继续等下去。

注意当鼠标点击事件正在执行的时候第一次的interval事件也触发了,与timer一样,它的事件也进入队列等待之后执行。然而,注意,当interval再次触发的时候(这个时候timer的事件正在执行),这一次它的事件被丢弃了。如果你在一个大的JavaScript代码块正在执行的时候把所有的interval回调函数都囤起来的话,其结果就是在JavaScript代码块执行完了之后会有一堆的interval事件被执行,而执行过程中不会有间隔。因此,取代的作法是浏览器情愿先等一等,以确保在一个interval进入队列的时候队列中没有别的interval。

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

最后,当第二个interval回调执行完后,我们可以看到队列已经被清空,没有什么需要JavaScript引擎去执行的了。这表明浏览器现在等待一个新的异步事件发生。于是在50ms的时候我们看到interval又触发了。这一样,由于没有什么东西挡住了它的执行,它马上就触发了。

让我们来看一个例子,这个例子更好地阐释了setTimeout和setInveral之间的区别。

  1. setTimeout(function(){
  2.     /* 一个很长的代码块…… */
  3.     setTimeout(arguments.callee, 10);
  4. }, 10);

  5. setInterval(function(){
  6.     /* 一个很长的代码块…… */
  7. }, 10);
复制代码
乍看上去,这两段代码在功能上似乎是相同的,可实际上并非如此。setTimeout的代码在前一次的回调执行完后总是至少会有10ms的延时(有可能会更多,但是绝对不会更少);而setInterval则总是在每10ms的时候尝试执行一次回调,它不管上一次回调是什么时候执行的。

我们在此学到了很多,让我们重述一下:

JavaScript引擎只有一个线程,这使得异步事件必需列队等待执行。 
setTimeout和setInterval在如何执行代码上有着本质地区别。 
如果一个timer在将要执行的时候被阻塞,它将会等待下一个时机(比预期的延时要长)。 
如果interval的执行时间较长(比指定的延时长),那么它们将连续地执行而没有延时。 
以上这些知识是相当重要的。知道JavaScript引擎的工作方式,尤其是知道它在有很多异步事件发生的时候是怎么工作的,为我们在写进阶的应用程序代码打下了坚实的基础。

分享到:
评论

相关推荐

    在JavaScript中用法timer示例_.docx

    JavaScript中的定时器是编程中常用的一种机制,用于在指定的时间间隔后执行特定的函数或代码。`setTimeout`和`setInterval`是JavaScript中两个主要的定时器函数,它们都允许开发者实现延迟执行或周期性执行的功能。...

    ASP.NET中的TIMER控件

    Timer控件能够通过简单的方法让开发人员无需通过复杂的JavaScript实现Timer控制。但是从另一方面来讲,Timer控件会占用大量的服务器资源,如果不停的进行客户端服务器的信息通信操作,很容易造成服务器当机。 因此...

    Countdown Timer in JavaScript.zip

    在这个"Countdown Timer in JavaScript"项目中,我们将探讨如何使用JavaScript来实现一个倒计时计时器。 首先,我们需要了解JavaScript中的Date对象。Date对象是JavaScript内置的,用于处理日期和时间的核心对象。...

    Timer控件的使用方法

    在Web环境中,Timer控件通常是一个JavaScript或者jQuery对象,它能够周期性地触发一个事件,比如每秒或每分钟执行一次特定的函数。这样,我们就可以利用这个特性来更新网页上的时间显示。 1. **引入必要的库**: ...

    Using a Timer in Javascript.zip

    "Using a Timer in Javascript.zip" 这个压缩包很可能包含了关于如何在JavaScript中使用定时器的教程或示例代码。在JavaScript中,我们主要使用两种类型的定时器:`setTimeout` 和 `setInterval`。 1. **setTimeout...

    timer:简单轻量级的 javascript 计时器

    计时器简单轻量级的 javascript 计时器开始在需要的地方包含 timer.min.js。 创建一个定时器实例:timer = new Timer ( < callback> , < instance> ); 调用 timer.start(duration) 函数。 每隔几秒,就会调用 ...

    timer组件显示图片

    `Timer`组件通常存在于各种编程框架中,例如.NET Framework(C#、VB.NET等)、Java(Swing、Android)以及JavaScript(浏览器环境)。在Windows Forms或WPF等桌面应用开发中,`System.Windows.Forms.Timer`是常用的`...

    在JavaScript中使用timer示例

    在JavaScript编程中,timers(计时器)是一种常用的机制,它允许你指定一个代码段,在未来某个特定的时间间隔之后执行。JavaScript提供了两种主要类型的timers:`setTimeout`和`setInterval`。`setTimeout`用于在...

    使用Timer的定时刷新

    `Timer` 控件的工作原理是基于 JavaScript 和服务器端事件的协同。在客户端,`Timer` 控件通过 JavaScript 代码周期性地触发回发,即模拟用户操作,使得页面能够定期与服务器进行通信,获取或更新数据。在服务器端,...

    C#窗体的timer

    这意味着,如果Timer控件在UpdatePanel控件内部,JavaScript计时组件只有在一次回传完成后才会重新建立。 Timer控件的主要方法包括Start()和Stop()。Start()方法用于启动时钟进行计时,而Stop()方法用于停止时钟。...

    asp.net中ajax程序使用timer控件

    在ASP.NET中,AJAX(Asynchronous JavaScript and XML)技术被广泛用于构建具有部分页面刷新功能的Web应用程序,从而提供更流畅的用户体验。Timer控件是ASP.NET AJAX Control Toolkit中的一个重要组件,它允许开发者...

    时钟Timer钟表Timer

    4. JavaScript:浏览器环境中使用setInterval和setTimeout函数,Node.js中可利用setInterval、setTimeout和process.nextTick方法。 5. C#:System.Threading命名空间下的Timer类提供了定时触发事件的能力。 五、...

    jquery timer, -.1.2.js

    jQuery Timer是一个用于在网页上实现定时任务的插件,它极大地简化了JavaScript中的setTimeout和clearTimeout方法的使用。在-.1.2.js这个版本中,我们找到了该插件的核心功能和优化之处。 首先,jQuery Timer的基本...

    ajax_timer.

    在Web开发中,AJAX (Asynchronous JavaScript and XML) 是一种用于创建交互式网页的重要技术。它允许在不刷新整个页面的情况下与服务器交换数据并更新部分网页内容。而“ajax_timer”似乎是指在AJAX应用中使用的...

    前端项目-d3-timer.zip

    在实际使用中,d3.timer的工作原理是通过调用一个回调函数,这个函数会根据设定的时间间隔不断执行,直到被明确地停止。开发者可以自定义这个回调函数来实现特定的动画效果,如平滑过渡、缩放、旋转等。通过d3.timer...

    timer实现倒计时

    在IT行业中,定时器(Timer)是一个非常关键的工具,它允许程序在特定时间间隔后执行某些任务,或者按照预设的时间点进行操作。这里我们主要讨论的是基于JavaScript的`setTimeout`和`setInterval`这两个常见的定时器...

    layer.timer

    5. **兼容性**:考虑到不同的浏览器环境,layer.timer通常会确保在主流的现代浏览器(如Chrome、Firefox、Safari、Edge)以及一些旧版本浏览器中都能正常工作,以满足广泛的用户群体。 6. **事件处理**:layer....

    jquery.timer.js 动态显示时间

    而jquery.timer.js插件正是jQuery生态中的一个优秀组件,专门用于动态显示时间。本文将深入探讨jquery.timer.js的使用方法、核心原理以及在实际项目中的应用。 一、jquery.timer.js简介 jquery.timer.js是一个轻量...

    JS-Timer.zip_ JS Timer_js Timer.js_js timer_timer.js

    在这个“JS Timer.zip”压缩包中,包含了一个用JS实现的计时器程序,它能从当前时间开始计时,并且具有良好的界面设计,使得用户体验更佳。 首先,我们来深入了解JavaScript中的定时器概念。在JavaScript中,有两个...

Global site tag (gtag.js) - Google Analytics