美文网首页
前端实现时间计时

前端实现时间计时

作者: 麦田_426 | 来源:发表于2023-12-21 10:43 被阅读0次

项目要求:

在前端界面上显示服务器的时间,格式是: yyyy-MM-dd hh:mm:ss 。 且误差控制在肉眼不可察觉

思路:

时间精确到秒,总不能一秒请求一次后台接口获取(资源耗费巨大,一段时间就会导致界面卡死)。 所以采用,一分钟请求一次接口进行时间校准,一分钟内,前端自行进行+1 处理来模拟秒数。

问题:

一开始采用,setInterval 做定时器+1 ,发现,运行一段时间,会有1-2s 的误差(其中还要解决定时器休眠,抖动等问题)
后采用requestAnimationFrame 解决以上问题。
但是新的问题来了,继续测试,依旧发现,会有半秒到一秒的误差。
最后让后台接口给我反馈回来,服务器当前时间的毫秒。 做毫秒的处理,才解决误差问题
最终代码如下:

代码

//获取服务器的时间
    async set_serve_time(){
      clearTimeout(this.servetimer);
      window.cancelAnimationFrame(this.timer_auto);
      const result = await getServeTimeApi(); //请求后台接口,获取服务器时间
      let startTime = Date.now();
      if(result.meta.status == 200){
        //console.log(result.data, 'result.data')
        let data = result.data.sec;  //服务器时间 yyyy-MM-dd hh:mm:ss
        let ms_data = Number(result.data.msec);  //服务器时间的 毫秒
        startTime = startTime - ms_data;  //开始时间去除服务器时间的毫秒; 减少误差

    
        this.$store.commit('setServe_ymd', data.split(' ')[0]);  
        this.$store.commit('setServe_hms', data.split(' ')[1]);
        let data_stamp = Date.parse(data) ; //日期转为时间戳(s)
       
        let loop = () => {
          let endTime = Date.now();
          let diffTime = endTime - startTime;
          if (diffTime  >= 1000) {
            startTime = endTime = Date.now();
            data_stamp = data_stamp + diffTime ;
            let data_format = dateFormat_one(data_stamp, 'yyyy-MM-dd hh:mm:ss');  //时间戳转日期
            const [time_ymd, time_hms] = data_format.split(' ');
            this.$store.commit('setServe_ymd', time_ymd);
            this.$store.commit('setServe_hms', time_hms);
          }
          this.timer_auto = window.requestAnimationFrame(loop);
        }
        loop();
      }else{
        clearTimeout(this.servetimer);
        window.cancelAnimationFrame(this.timer_auto);
        this.$store.commit('setServe_ymd', '-');
        this.$store.commit('setServe_hms', '-');
      }
      this.servetimer = setTimeout(this.set_serve_time, 1 * 60 * 1000);
    },

解释

其中,startTime = startTime - ms_data; 至关重要。 因为,仔细思考全过程,如果我们不考虑服务器时间的毫秒,假设当前服务器时间是17:17:17: 980 , 前端拿到的时候就是17:17:17 , 但此时服务器真正的时间已经是17:17:18了 ,这个误差就大了。
再加上从后台获取到服务器时间,这个过程本身有一定是时间延迟。

最终测试,时间误差控制做了肉眼不可识别的程度。

相关文章

网友评论

      本文标题:前端实现时间计时

      本文链接:https://www.haomeiwen.com/subject/xtnxndtx.html