本文地址:【http://www.xiabingbao.com/javascript/2015/04/20/javascript-timer/

  在以前的文章【javascript中的定时器】中,简单的介绍了一下setTimeout()和setInterval()两个定时器方法的使用和原理。不过在昨天给我的node即时聊天系统添加消息提示时,发现了定时器新的特性。当然,这对于我来说是新的发现,其实这些东西早就已经存在了。

  1. 最小运行时间间隔

  在setTimeout()和setInterval()我们能够设定时间间隔,来让下个事件大致发生在哪个时间段。假如我们设置时间间隔是0的话,那是不是就会在0ms之后执行呢,也就是立即执行。我们可以采用下面的代码输出一下:

function get(){
var timer = null;
var date = null;
var diff = 0;
var last = 0;
var now = 0;
var nums = 0;
var color = '#000';
var process = document.getElementById("process");
timer = setInterval(function(){
date = new Date();
now = date.getTime();
diff = now-last; // 前后两个时间差
last = now;
nums++;
color = diff===0?'#f00':'#000';
process.innerHTML += '<p>'+now+' (<span style="color:'+color+'">'+diff+'</span>)</p>'; if(nums>=100){
clearInterval(timer);
}
}, 0);
}
get();

  我们把每次执行setInterval()前后的时间差打印到屏幕中(以下数据使用chrome 42.0.2311.90版本测试):

1429545782409 (1)
1429545782412 (3)
1429545782414 (2)
1429545782420 (6)
1429545782425 (5)
1429545782430 (5)
1429545782437 (7)
1429545782443 (6)
1429545782449 (6)
1429545782454 (5)
1429545782460 (6)
1429545782466 (6)
1429545782471 (5)
1429545782476 (5)
...

   从打印出的数据可以看出,setInterval()的时间间隔为0ms时,输出的时间差基本都在1~10ms之间,也是能在可以接受的范围内。IE11下的测试与chrome的数据基本一致,而在firefox下能够出现0的时间差。

  2. 标签不可见时的定时器间隔

  其实不管是把时间间隔设定为0ms还是其他的时间间隔,运行时都会有时间误差的,比设定的间隔多1~16ms毫秒左右,有的时候还会相差更多。

  我们有时会在某个场合对标题进行闪动,提示给用户当前标签页有新消息产生:

var backup = document.title; // 存储原标题
function blink(){
document.title = document.title == backup? "【有新消息】" : backup;
}
blink();
timer = setInterval(blink, 500);

  上面的代码能够进行500ms的标题轮流闪动,当我们处在当前标签页时,基本感觉不出定时器产生的误差。可是如果我们切换到其他的标签页或者最小化时,我们就能够看到,标题的闪动变慢了很多,差不多提升到1000ms左右了。

  为了更加准确的记录时间间隔的变化,我们特此将上面的代码进行如下的补充,标题进行闪动时记录当前的毫秒时间戳,同时标记出当前标签页可见时的状态和不可见时的状态【查看演示】:

 // 标题闪动
function blinkTile(title, timeout){
var self = this;
var timer = null;
var backup = document.title;
var last = 0;
var process = document.getElementById("process"); self.init = function(title, timeou){
if(title != undefined){
self.title = title;
}
self.timeout = timeout == undefined? 500: timeout;
} self.start = function(){
self.stop(); function blink(){
document.title = document.title == backup? self.title : backup;
self.check();
}
blink();
timer = setInterval(blink, self.timeout);
} self.stop = function(){
if(timer != null){
document.title = backup;
clearInterval(timer);
timer = null;
}
} // 打印时间差,同时让滚动条在最下边
self.check = function(){
var date = new Date();
var now = date.getTime();
var diff = now-last;
last = now;
process.innerHTML += '<p>'+now+' ('+diff+')</p>';
process.scrollTop = process.scrollHeight;
} self.init(title, timeout);
}
var blink = new blinkTile('【新消息】', 500);
blink.start(); // 标签页的可见状态
var hidden, state, visibilityChange;
if (typeof document.hidden !== "undefined") {
hidden = "hidden";
visibilityChange = "visibilitychange";
state = "visibilityState";
} else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
state = "mozVisibilityState";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
state = "msVisibilityState";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
state = "webkitVisibilityState";
} var process = document.getElementById("process");
// 添加监听器,在title里显示状态变化
document.addEventListener(visibilityChange, function() {
if(document[state]=="hidden"){
process.innerHTML += '<p style="color:#f00;">====== 离开 ======</p>';
}else{
process.innerHTML += '<p style="color:#f00;">++++++ 回来 ++++++</p>';
}
}, false);

  运行后,我们能够看到程序记录下的数据有(以下仅是部分数据):

1429547223336 (505)
1429547223837 (501)
====== 离开 ======
1429547225296 (1459)
1429547226296 (1000)
1429547227296 (1000)
1429547228297 (1001)
++++++ 回来 ++++++
1429547229137 (840)
1429547229637 (500)

  我们很清楚的看到,当标签页不可见时(“离开”后),时间差上升了1000ms左右;标签页可见时(“回来”后),时间差又恢复到了500ms左右。不过在标签页刚切换完的时候,时间差的变化比较大,后来就趋于稳定了。其实浏览器为了在标签页不可见时减少CPU的利用率和电池等的消耗,特地将时间间隔进行提高。

  不过这里要指出的是,在IE11下,标签的可见状态不会影响定时器的时间间隔。

  3. 总结

  上面的代码中,我们设定的时间间隔是500ms,标签页不可见时,时间间隔就会提升到1000ms;如果我们把时间间隔设定到1500ms呢,2500ms,可以修改程序运行一下,是否能发现什么规律。

  博客地址:http://www.xiabingbao.com

javascript中的定时器的更多相关文章

  1. 浅谈JavaScript中的定时器

    引言 使用setTimeout()和setInterval()创建的定时器可以实现很多有意思的功能.很多人认为定时器是一个单独的线程(之前我也是),但是JavaScript是运行在单线程环境中的,而定 ...

  2. [ Javascript ] JavaScript中的定时器(Timer) 是怎样工作的!

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

  3. javascript中的定时器入门

    JavaScript提供定时器(timer)的功能,可以延期执行或重复执行函数或代码段. window对象提供了三个方法来实现定时器的效果,分别是setTimeout().setInternal()和 ...

  4. javascript中的计时器

    javascript中的定时器有两种:一种是一次性定时器,一种是可以持续使用的定时器: 1:一次性定时器setTimeout(a,b):兼容ie的任何版本 该方法接受两个参数,第一个是要执行的代码,第 ...

  5. Unity中的定时器与延时器

    JavaScript中的定时器与延时器,分别是 setInterval.setTimeout,对应的清理函数是:clearInterval.clearTimeout. 而在Unity中,则分别是:In ...

  6. Javascript中定时器的使用方法

    Javascript中定时器的使用方法 1.间隔定时器(每隔一段时间执行一次代码) 格式:setInterval(函数,时间) //时间单位是毫秒,每隔设置的时间执行函数里的内容一遍(一直执行) // ...

  7. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  8. JavaScript中的this指向

    this是谁 技术一般水平有限,有什么错的地方,望大家指正. this代指当前对象super调用父类的构造函数,应表会运网数物,加载驱动建立链接执行SQL处理结果,直到现在每想起这三点就能想起我上大学 ...

  9. 通过一道笔试题浅谈javascript中的promise对象

    因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...

随机推荐

  1. Push h.264 rawdata to rtmp server

    Push h.264 rawdata to rtmp server /* The MIT License (MIT) Copyright (c) 2013-2015 SRS(ossrs) Permis ...

  2. 谷歌浏览器Chrome错误提示Flash过期怎么办(转)

    在使用谷歌浏览器Chrome时,会碰到谷歌浏览器Chrome的错误提示:“Adobe Flash Player因过期而遭到阻止”,点击“更新插件”是不行的,国内的网络根本就打不开,点击“运行一次”是可 ...

  3. lua全局状态机

    本文内容基于版本:Lua 5.3.0 global_State概述 global_State结构,我们可以称之为Lua全局状态机.从Lua的使用者角度来看,global_State结构是完全感知不到的 ...

  4. ios极光推送快速集成教程

    内容中包含 base64string 图片造成字符过多,拒绝显示

  5. Objective-C中的alloc和init问题

    从开始学的NSString *name=[[NSString alloc] init] 起,仅仅这句话是分配内存空间,一直在用,从来没考虑过它的内部是怎么实现的.今天无意中看到了这一句代码: NSSt ...

  6. 自己写个 Drools 文件语法检查工具——栈的应用之编译器检测语法错误

    一.背景 当前自己开发的 Android 项目是一个智能推荐系统,用到 drools 规则引擎,于我来说是一个新知识点,以前都没听说过的东东,不过用起来也不算太难,经过一段时间学习,基本掌握.关于 d ...

  7. 88. Merge Sorted Array(从后向前复制)

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note:Yo ...

  8. 安卓 和 IOS 的icon 尺寸

    安卓 36*36 48*48 72*72 96*96 IOS Icon.png – 57×57 iPhone (ios5/6) Icon@2x.png – 114×114 iPhone Retina  ...

  9. eclipse中添加tomcat ServerName 无法输入

    Eclipse的开发过程中,无法从以下方式,添加Tomcat服务器.  其中ServerName是被置为灰色的,无法编辑.  如何解决 1.  关闭Eclipse 2.  打开WorkSpace所在的 ...

  10. 20145316许心远《Java学习笔记(第8版)》课程总结

    20145316许心远<Java学习笔记(第8版)>课程总结 每周读书笔记链接汇总 ▪ 第一周读书笔记 ▪ 第二周读书笔记 ▪ 第三周读书笔记 ▪ 第四周读书笔记 ▪ 第五周读书笔记 ▪ ...