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 
    ......
    

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

  • 相关阅读:
    mysql access denied for user root Mysql用户无权限
    远程链接调用sql脚本
    CuteEditor使用详解
    如何设置release模式
    ShardingJDBC不分库,只分表例子
    SpringCloud Stream整合RocketMQ实现消息发送与接收
    Spring Cloud Gateway的PrefixPath及StripPrefix功能
    使用MongoDB的Spring Boot和MongoTemplate教程
    ShardingJDBC读写分离案例
    SpringBoot那些好用的连接池HikariCP
  • 原文地址:https://www.cnblogs.com/flash3d/p/3715600.html
Copyright © 2011-2022 走看看