首页 web前端 js教程 JavaScript 计时器的工作原理

JavaScript 计时器的工作原理

Nov 25, 2016 am 09:15 AM
javascript

看下面内容之前,看一小段代码,如果读者能说出代码的用意,那就没必要往下看了,因为你都懂。

setTimeout(function(){
/* Some long block of code… */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/* Some long block of code… */
}, 10);
登录后复制
登录后复制

计时器是一个很牛X的东西,但是很多人其实只限于知道它的语法,缺乏对其原理的认识。计时器通过设定一定的时间段(毫秒)来异步的执行一段代码。因为 Javascript 是一个单线程语言,计时器提供了一种绕过这种语言限制来执行代码的能力。

今天就简单的来说下计时器的工作原理。

JavaScript 提供了三个函数来构建和操作计时器

1 var id = setTimeout(fn, delay);

2 var id = setInterval(fn, delay);

3 clearInterval(id); clearTimeout(id);

具体的语法我就不多说了,可以查手册。为了了解计时器的工作原理,有一个概念必须记在心里:时间延迟不能被保证。什么意思,就是说你这样写setTimeout(fn, 500)并不代表fn肯定在500毫秒之后马上就执行,延迟很可能会更长。因为 JavaScript 是单线程语言,所有的异步事件(包括计时器、鼠标事件或者一个 XMLHttpRequest 完成)仅仅当程序执行期间有缺口的时候才会执行,不是你规定了什么时候就什么时候执行,要知道程序员不是万能的,你写的东西最终还是要看浏览器脸色的。

下面的这张图片可以很好的说明问题,感谢 John Resig 大神。

0827214828b3486d2d_13_0.png

从上往下看,左面的数字代表时间(毫秒),右面的文字代表了一系列异步事件的设置和触发,中间则是代码块。最上面的 JavaScript 代码块可能是你在浏览器载入的时候执行的片段,大概耗时18毫秒,紧接着下面的 Mouse Click Callback 代码块可能是你一个鼠标事件触发时的回调函数,大概耗时11毫秒,依次类推。

JavaScript 的单线程特性决定了每次只能执行一块,所以当第一块代码执行的时候(它一共运行了18毫秒),本身构造了两个计时器,期间可能用户还点了一下鼠标(你有过在网页一打开还没载完就在那乱点的情况吗)。按理说用户点完鼠标就应该马上执行那个回调函数,但是不行,JavaScript 执行只有一条道嘛,在那18毫秒没跑完之前,其他代码块想执行就只能排队,没空间给你超车都。那两个计时器都是10毫秒的延迟,从图中可以看到,setTimeout也在那18毫秒执行结束之前触发了,没办法也排队吧。

终于,18毫秒后,天上一道神雷把前面的车直接劈成空气了,后面两个排队的可以过去了,但是还得一个一个,不能并列,那谁先过去呢?是不是两个人在那划拳?不是的,浏览器说的算,浏览器说,鼠标单击事件先过去,setTimeout只能继续等11毫秒。注意看图,在鼠标事件回调函数执行的时候,又一个计时器事件触发了(setInterval),等着,而且必须排在setTimeout的后面。

11毫秒过去了,setTimeout 终于可以过去了,注意看,setInterval 的第二次触发了,虽然它第一次都在排队呢,如果这个时候还向往常一样排队,最后是什么情况,setTimeout执行完了,就会连续执行两个setInterval,你设置的延迟没用了都。所以浏览器还是比较智能的,它在处理setInterval的时候,如果发现已经有排队的,就直接把新来的 Kill 掉。

接着看,轮到排队的 setInterval 第一次触发开始执行了,它执行的时候,第三次触发又到了,这一次没有排队了,所以浏览器没把它 Kill 掉,给丫排队的机会,所以你会发现这两次的setInterval的执行没有间隔的,如果你做一个幻灯片,遇到这种情况就要好好想想自己的代码是不是有问题了。

最后,再也没有别的因素干扰了 setInterval 了(假如用户被 MM 叫走了),setInterval 就按照你想要的步骤执行了。

讲到这里,开头的代码可以理解了吧。

setTimeout(function(){
/* Some long block of code… */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/* Some long block of code… */
}, 10);
登录后复制
登录后复制

这两个函数看起来效果一样,其实不然,第一个代码块总会延迟10毫秒执行,虽然大多时候是大于10毫秒的。而第二个每到10毫秒就尝试执行,不管之前的触发执行了没有。

总结起来四条

• JavaScript 引擎只有一个线程,它会迫使某些异步事件排队

• setTimeout 和 setInterval 在执行异步代码的时候有很大区别

• 假如一个计时器被阻止执行,它会等待知道遇到一个代码执行空隙,通常时间比预计的要长

• Intervals 可能会一个挨着一个执行,如果回调函数的执行时间大于间隔


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

如何在JavaScript中获取HTTP状态码的简单方法 如何在JavaScript中获取HTTP状态码的简单方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务

See all articles