setInterval和setTimeout 的主要区别,使用setTimeout 代替setInterval

import { v4 as uuid } from 'uuid'

class IntervalTimer {
  constructor (params) {
    this.timerList = []
    this.options = Object.assign({}, {
      delay: 1000
    }, params)
  }

  /**
   * 添加定时器
   * @param {*} callback 回调执行函数
   * @param {*} delay 延迟时间
   * @param {*} immediate 是否立即执行
   * @returns
   */
  addTimer (callback, delay = this.options.delay, immediate = false) {
    let timerId = uuid()
    let timer = {
      id: timerId,
      callback,
      delay,
      count: 0, // 执行次数
      timestamp: new Date().getTime()
    }
    this.timerList.push(timer)
    if (immediate) {
      this._execute(timer)
    } else {
      this._runTimer(timer)
    }

    return timerId
  }

  _runTimer (timer) {
    timer.target = setTimeout(this._execute.bind(this), timer.delay, timer)
  }

  _execute (task) {
    task.count++
    let current = new Date().getTime()
    let duration = current - task.timestamp
    task.timestamp = current
    task.callback(task.count, duration) // 回调参数:当前执行次数,实际间隔时长(毫秒)
    // clearTimeout(task.target)
    this._runTimer(task)
  }

  clearTimer (timerId) {
    const taskIndex = this.timerList.findIndex(item => item.id === timerId)
    if (taskIndex !== -1) {
      // 由于删除该计时器时可能存在该计时器已经入栈,所以要先清除掉,防止添加的时候重复计时
      clearTimeout(this.timerList[taskIndex].target)
      let count = this.timerList[taskIndex].count
      this.timerList.splice(taskIndex, 1)
      return count
    }
  }

  dispose () {
    let list = this.timerList.map(item => item.id)
    list.forEach(item => this.clearTimer(item))
  }
}

export default new IntervalTimer()

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容