zoukankan      html  css  js  c++  java
  • 解决setInterval计时器不准的问题

    在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,因为setInterval的回调函数并不是到时后立即执行,而是等系统计算资源空闲下来后才会执行.而下一次触发时间则是在setInterval回调函数执行完毕之后才开始计时,所以如果setInterval内执行的计算过于耗时,或者有其他耗时任务在执行,setInterval的计时会越来越不准,延迟很厉害.

    下面的代码可以说明这个问题

    var startTime = new Date().getTime();
    var count = 0;
    //耗时任务
    setInterval(function(){
    	var i = 0;
    	while(i++ < 100000000);
    }, 0);
    setInterval(function(){
    	count++;
    	console.log(new Date().getTime() - (startTime + count * 1000));
    }, 1000);
    

    代码里输出了setInterval触发时间和应该正确触发时间的延迟毫秒数

    176
    340
    495
    652
    807
    961
    1114
    1268
    1425
    1579
    1734
    1888
    2048
    2201
    2357
    2521
    2679
    2834
    2996 
    ......
    

    可以看到延迟是越来越严重的.

    为了在js里可以使用相对准确的计时功能,我们可以

    var startTime = new Date().getTime();
    var count = 0;
    setInterval(function(){
    	var i = 0;
    	while(i++ < 100000000);
    }, 0);
    function fixed() {
    	count++;
    	var offset = new Date().getTime() - (startTime + count * 1000);
    	var nextTime = 1000 - offset;
    	if (nextTime < 0) nextTime = 0;
    	setTimeout(fixed, nextTime);
    	
    	console.log(new Date().getTime() - (startTime + count * 1000));
    }
    setTimeout(fixed, 1000);
    

    代码里,通过1000(也就是周期时间)减去当前时间和准确时间的差距,来算出下次触发的时间,从而修正了当前触发的延迟.

    下面是输出

    186
    200
    230
    271
    158
    899
    900
    899
    900
    899
    899
    899
    902
    899
    418
    202
    232
    266
    145
    174
    192
    214
    242
    268
    149
    179
    214 
    ......
    

    可以看到虽然触发时间并非绝对准确,但由于每次触发都进行及时修正,所以并没有造成误差积累.

  • 相关阅读:
    Windows 服务的安装(1)
    C#编写window服务,一步一步(1)
    .net 读写记事本文件
    C#中POST数据和接收的几种方式(抛砖引玉)
    Newtonsoft.Json 通过 JObject 读取 json对像 超简单
    Winform读写App.config文件以及重启程序
    WebMatrix之WebMatrix.Data
    C#中方法的参数的四种类型
    zh-Hans vs.net 通过 管理nuget程序包下载简体中文语言包 zh-cn
    .net C# 图片转Base64 Base64转图片
  • 原文地址:https://www.cnblogs.com/flash3d/p/3715600.html
Copyright © 2011-2022 走看看