js实现一个setTimeout模拟setInterval的类管理工具

内容分享10小时前发布
0 0 0

isFunction 可以看这篇文章 js判断参数类型的实用工具

import { isFunction } from  @utils/util.type.js 

class SetInterval {
  constructor () {
    this.tasks = new Map()
  }

  /**
   * @description: 添加定时器方法
   * @param {any} name
   * @param {async function} callback 必须是异步函数
   * @param {number} wait 等待时间 默认一秒
   * @param {boolean} leading 是否先执行一次
   * @return {undefined}
   */
  add = async (name, callback, wait = 1000, leading = false) => {
    if (!name) {
      console.error( Setinterval => add => 必须传入name )
      return
    }

    if (this.tasks.has(name)) {
      console.error(`Setinterval => add => 已有一样name名字定时器, 请更换name名 => ${name}`)
      return
    }

    if (!isFunction(callback)) {
      console.error( Setinterval => add => callback必须为一个函数 )
      return
    }

    console.log(`%c添加定时器[${name}]成功, 刷新间隔为[${wait}]毫秒, ${leading ?  已  :  未 }开启先执行一次callback功能`,  color: #24c59d; font-weight: 700 )

    // 定时器前先执行一次函数
    try {
      leading && await callback()
    } catch (error) {
      console.error(`SetInterval => add => 定时器 [${name}] 执行出错, 错误缘由 => ${error}`,  color: #24c59d; font-weight: 700 )
    }

    this.tasks.set(name, { wait, callback })

    this.run(name)
  }

  /**
   * @description: 将定时任务添加到队列中
   * @param {string} name 定时器名称
   * @return {*}
   */
  run = name => {
    const inner = () => {
      const task = this.tasks.get(name)
      if (task) {
        this[name] = setTimeout(async () => {
          try {
            await task.callback()
          } catch (error) {
            console.error(`SetInterval => run => inner => 定时器 [${name}] 执行出错, 错误缘由 => ${error}`)
          } finally {
            this.closeTimeout(name)
            inner()
          }
        }, task.wait)
      }
    }
    inner()
  }

  /**
   * @description: 关闭某个定时器
   * @param {string} name 定时器名称
   * @return {*}
   */
  closeTimeout = name => {
    clearTimeout(this[name])
    this[name] = null
  }

  /**
   * @description: 外部调用关闭某个定时器
   * @param {any} name 定时器名称
   * @return {*}
   */
  close = name => {
    try {
      const task = this.tasks.get(name)

      if (task) {
        this.tasks.delete(name)
        this.closeTimeout(name)
        console.log(`%c关闭定时器[${name}]成功`,  color: #24c59d; font-weight: 700 )
      } else {
        console.error(`SetInterval => close => 未找到 [${name}] 定时器`)
      }
    } catch (error) {
      console.error( SetInterval => close => 删除task失败 => 失败缘由 =>  , error)
    }
  }
}

export default new SetInterval()

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...