为了账号安全,请及时绑定邮箱和手机立即绑定

我的这段js倒计时为什么越走越慢?

我的这段js倒计时为什么越走越慢?

湖上湖 2019-03-13 18:15:58
var orderTimeOut = 900000;var timer = setInterval(() => {  orderTimeOut -= 10;  if (orderTimeOut > 10) {     times = overTime(orderTimeOut);     console.log(times)  }else {    orderTimeOut = 0;    times = "00:00:00";  }}, 10);function overTime(time) {  var a = (time % 1000).toString().substr(0, 2);  var b = Math.floor(time / 1000);  var m = b % 60;  m = String(m);  m = m.length >= 2 ? m : "0" + m;  var f = Math.floor(time / (1000 * 60));  f = String(f);  f = f.length >= 2 ? f : "0" + f;  return f + ":" + m + "." + a;}这段方法 能够正常进行倒计时,但是观察到,它似乎越跑越慢.....
查看完整描述

3 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

无论是setInterval还是setTimeout,时间肯定是不对的。

计时器逻辑是task执行完成后,查看timer是否过时,如果过时,执行timer回调。

也就是说如果有同步方法在运行,那么计时器的回调就会延后,而如果倒计时很久,这个延后的时间累加就会造成和真实时间不同步。


let i = 0;

setInterval(() => {

  if (i === 0) {

    console.log('start', Date.now())

    let lastTime = new Date().getTime() + 10 * 1000;//暂停10s 

    while (lastTime > new Date().getTime()) {


    }

  }

  i++;

  console.log(i, Date.now())//以后的时间都延迟了10s+


}, 1000)


查看完整回答
反对 回复 2019-04-03
?
慕村9548890

TA贡献1884条经验 获得超4个赞

刚做了下测试,在一个只运行此方法的页面上,对比系统时间进度,还是很同步的。
实际项目中,运行的功能比较多,而setInterval会将事件放到当前队列的最后执行,看起来的确有点卡壳。
不过实际应该不会变慢,如果我理解的setInterval没错的话。
setInterval,浏览器会单独开一个线程,每隔几毫秒将此方法扔进JS队列。
每隔几秒是比较固定的,但什么时候执行放进去的代码却是不可控的。
如果当前队列的事情比较多,短时间不会执行此方法,看起来就变慢了。不过相应的,也会在某个时刻一次性执行很多次此方法。


补充另个相对优化的倒计时方法。
接到要倒计时的总时间T,并记下当前的时间tStart
使用setTimeout隔一段时间执行方法,方法里结合三个变量的关系(加上现在的时间)算出剩余时间。
再次调用setTimeout重复操作。


查看完整回答
反对 回复 2019-04-03
?
函数式编程

TA贡献1807条经验 获得超9个赞

大概像这样,区别点在得到剩余时间的方式,不是每次减几而是看时间具体经过了多少。

运行这个程序,你可以发现,每次打印的时间间隔都不相同,相当有时计时器会有卡壳。

这在JS理避免不了的,能做的就是在每次刷新时间时,保证是正确的时间,并尽量减少不必要的刷新。


let timeTotal = 30000;

let timePrevious = Date.now();


printTime();

disturbFunction();


function printTime() {

  let timeNow = Date.now();

  let timeJap = timeNow - timePrevious;

  let timeLeft = timeTotal - timeJap;


  timePrevious = timeNow;


  if (timeLeft > 0) {

    setTimeout(() => printTime(), 500);

    console.log('Jap:', timeJap, '. Left:', timeLeft);

  } else {

    console.log('Jap:', timeJap, '. Left:', 0);

  }

}


function disturbFunction() {

  let i = 100000;

  while (i--) {


查看完整回答
反对 回复 2019-04-03
  • 3 回答
  • 0 关注
  • 534 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信