摸鱼写一个TS 秒表计时类

2021-06-24 14:51:01 浏览数 (1)

目标

类似手机秒表功能,调用记录api,记录当前时间戳。 可获取一段或多段时间间隔,可获取跨时段间隔。

使用

代码语言:javascript复制
// 时间格式化
import dayjs from 'dayjs'

// 延时
function delay(time:number, callback?:Function) {
  return new Promise((reslove) => {
    setTimeout(() => {
      reslove(callback ? callback() : undefined)
    }, time * 1000)
  }) 
}


async function run() {
  
  const c = new Clock()

  c.tick()
  await delay(1)
  c.tick()
  await delay(3)
  c.tick()
  await delay(10)
  c.tick()

  let t = c.nextTick()
  while (t !== Clock.END) {
    // 遍历获取每段时间间隔
    console.log(t as number / 1000)
    t = c.nextTick()
  }
  
  // 1.016
  // 3.013
  // 10.018
  
  // 格式输出每个时间记录点
  c._getTimes().forEach(i => {
    dayjs(new Date(i)).format('YYYY/MM/DD HH:mm:ss')
  }) 
}

run()

源码实现

代码语言:javascript复制
/**
 * 计时器
 * @summary 
 * 记录一段或多段时间间隔
 */
export class Clock{

 // 迭代器终止标识
 static END = 'END'

// 工厂函数
 static create() {
   return new Clock()
 }

  private _times:number[] = []
  private _currentTick: number = 0
  
  // 获取记录列表
  _getTimes() {
    return [...this._times]
  }
  
  /**
   * 打点记录
   */
  tick() {
    this._times.push((new Date()).getTime())      
  }

  /**
   * 清空记录
   */
  clean() {
    this._times = []
  }
  
  /**
   * 记录条数
   * @returns number
   */
  len() {
    return this._times.length
  }

  /**
   * 获取记录间隔
   * @param start 
   * @param end 
   * @returns 
   */
  getTick(start:number, end: number) {
    const startTime = this._times[start]
    const endTime = this._times[end]
    if (!startTime || !endTime) {
      throw new Error(`查询越界: ${start} - ${end}`)
    }
    return endTime - startTime
  }

  /**
   * 最后一条间隔
   * @returns number
   */
  lastTick() {
    return this.getTick(this._times.length - 2, this._times.length - 1)
  }

  /**
   * 第一条间隔
   * @returns number
   */
  firstTick() {
    return this.getTick(0, 1)
  }
  
  /**
   * 每条间隔迭代器
   * @returns number
   */
  nextTick() {
    if (this._currentTick >= this._times.length - 1) {
      return Clock.END
    }
    
    const current = this._currentTick
    const next = this._currentTick  = 1
    
    return this.getTick(current, next)
  }

  /**
   * 重置迭代器指针
   */
  resetTick() {
    this._currentTick = 0
  }

  /**
   * 当前迭代器指针位置
   */
  currentTick() {
    return this._currentTick
  }
}

0 人点赞