让前端飞javascriptjs css html

js 指定时间点执行事件(定点定时刷新)

2022-08-26  本文已影响0人  阿巳交不起水电费

项目中经常有定时任务,但是不知道在某个时间点定时刷新的需求你们有没有遇到过。

现有需求如下:
需要在每日的8点、12点、17点刷新页面某个部分的数据,这个时间点可以是任意时刻,只有在指定的时刻才执行局部刷新。

代码:

<template>
  <div class="hello">
    <h1>js定时定点刷新</h1>
  </div>
</template>

<script>
import moment from 'moment';

export default {
  name: 'testFn',
  data() {
    return {
      timer: null,
    }
  },
  mounted() {
    this.getData()
  },
  beforeDestroy() {
    this.timer && clearInterval(this.timer)
  },
  methods: {
    getData() {
      this.timer && clearInterval(this.timer)
      new Promise((resolve, reject) => {
        console.log('数据获取成功。。。')
        resolve()
      }).finally(() => {
        this.intervalFixedPointTaskFn({
          timeFixedArr: ['08:00:00', '12:00:00', '17:00:00'],
          delayTime: 1000
        })
      }, this.getData)
    },
    /**
     * 定点定时刷新
     * @timeFixedArr:Array<String>需要刷新的时间点,格式如['08:30:00','12:00:05']
     * @delayTime: Number 延迟的ms,在固定的实际点后多少ms内都只执行一次
     * @tickerFn:需要定时刷新的方法
     * */
    intervalFixedPointTaskFn({timeFixedArr = [], delayTime = 1000}, tickerFn) {
      let executed = true // true代表需要定时刷新的方法是否执行了,后面纵使在设定时间范围内也不执行自动刷新
      this.timer && clearInterval(this.timer) // 清除定时器
      this.timer = setInterval(() => {
        console.log('timer...')
        let currentTime = new Date().getTime() // 当前时间
        let currentYMD = moment(currentTime).format('YYYY-MM-DD') // 当前年月日
        let refresh = false // 判断是否需要刷新
        // 判断是否在设定的时间范围内
        let count = 0 // 记录不在设定范围内的数量
        for (let i = 0; i < timeFixedArr.length; i++) {
          let item = timeFixedArr[i] // 固定的时分秒
          let setTime = new Date(`${currentYMD} ${item}`).getTime() // 完整时间
          // console.log(executed, 111)
          // console.log(currentTime, setTime, setTime + delayTime)
          // console.log(moment(currentTime).format('YYYY-MM-DD HH:mm:ss'),moment(setTime).format('YYYY-MM-DD HH:mm:ss'),moment(setTime + delayTime).format('YYYY-MM-DD HH:mm:ss'))
          if (currentTime >= setTime && currentTime <= (setTime + delayTime)) { // 没有刷新过且在设定时间范围内 - 刷新
            if (!executed) { // 只执行一次
              refresh = true
            }
            break
          } else {
            count++
          }
        }

        if (count === timeFixedArr.length) {
          executed = false
        }

        if (refresh) {
          executed = true
          console.log(`${moment(currentTime).format('YYYY-MM-DD HH:mm:ss')} 执行定时任务....`)
          tickerFn && tickerFn()
        }

      }, 1000)
    }
  }
}
</script>
<style scoped lang="less">
</style>

注意:

intervalFixedPointTaskFn方法的delayTime参数至少也要是1000毫秒,因为代码执行需要时间,可能代码执行时的时间戳不会刚好和设定时间点的时间戳相等,因此最好设置一个设定时间的延长时间,在设定时间到这个延长时间范围内,都算做是这个时刻,以此保证在这个时间点附近一定会执行刷新。
错误例子如下:

image.png
image.png
打印如下: image.png
可以看到currentTimesetTime的时间戳相差76ms,不相等。

若对你有帮助,请点个赞吧,谢谢支持!
本文地址:https://www.jianshu.com/p/d658abc76325,转载请注明出处,谢谢。

上一篇下一篇

猜你喜欢

热点阅读