javascript setInterval不能正确延时

javascript是一个单线程语言,只有一个主线程在程序中运行,如果有io请求,是浏览器的线程池(注意:浏览器是多线程的)去处理,等结果放回(把回调放回到主线程的执行队列中,并不能马上执行),回到主线程中去处理,所以javascript可以给人一种多线程的感觉。

所以基于上述条件,像setInterval(func, 0)和setTimeout(func, 0)这样的语句,也不没有马上执行他,而是放到执行队列的后面,执行完前面的队列,才轮到setInterval和setTimeout。

而setInterval(func, 100)也是一样的,在100毫秒后,把func放到队列的后面,并没有在100毫秒后马上执行他,所以引出题目的讨论。

如下代码:

var interval = 0;
var self = this;
var startTime = new Date().getTime();
var count = 0;
var callback2 = function() {
    count++;
    var offset = new Date().getTime() - (startTime + count * 100);
    var nextTime = 100 - offset;
    if (nextTime < 0) {
          nextTime = 0;
    }
    for (var i=0; i<=1000000000; i++) {

    }
    console.log(offset);
  }
window.setInterval(callback2, 100);

如果在setInterval的回调里,需要执行代码的时间比较长,比如循环百万千万次;或者就算你写的代码很完美,效率很高,但是只要用户把浏览器压后台、切换网页标签等让浏览器不显示的操作,都会让上述代码出现下面的结果:


结果是:每次都会延迟几百毫秒,且会叠加。


对于上述问题的解决方法是:

var callback = function() {
    count++;
    var offset = new Date().getTime() - (startTime + count * 1000);
    var nextTime = 1000 - offset;
    if (nextTime < 0) {
          nextTime = 0;
    }
    for (var i=0; i<=1000000000; i++) {

    }
    console.log(offset);
    setTimeout(callback, nextTime);
  }
interval = window.setTimeout(callback, 1000);
通过 当前时间的判断,将每次延迟的时间在下次执行的时候矫正回来。

上述代码执行的结果是:


结果:每次执行还是会有延迟,但是不会叠加。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值