js實(shí)現(xiàn)一個(gè)setTimeout模擬setInterval的類管理工具

isFunction 可以看這篇文章 js判斷參數(shù)類型的實(shí)用工具

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

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

  /**
   * @description: 添加定時(shí)器方法
   * @param {any} name
   * @param {async function} callback 必須是異步函數(shù)
   * @param {number} wait 等待時(shí)間 默認(rèn)一秒
   * @param {boolean} leading 是否先執(zhí)行一次
   * @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名字定時(shí)器, 請(qǐng)更換name名 => ${name}`)
      return
    }

    if (!isFunction(callback)) {
      console.error('Setinterval => add => callback必須為一個(gè)函數(shù)')
      return
    }

    console.log(`%c添加定時(shí)器[${name}]成功, 刷新間隔為[${wait}]毫秒, ${leading ? '已' : '未'}開啟先執(zhí)行一次callback功能`, 'color: #24c59d; font-weight: 700')

    // 定時(shí)器前先執(zhí)行一次函數(shù)
    try {
      leading && await callback()
    } catch (error) {
      console.error(`SetInterval => add => 定時(shí)器 [${name}] 執(zhí)行出錯(cuò), 錯(cuò)誤原因 => ${error}`, 'color: #24c59d; font-weight: 700')
    }

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

    this.run(name)
  }

  /**
   * @description: 將定時(shí)任務(wù)添加到隊(duì)列中
   * @param {string} name 定時(shí)器名稱
   * @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 => 定時(shí)器 [${name}] 執(zhí)行出錯(cuò), 錯(cuò)誤原因 => ${error}`)
          } finally {
            this.closeTimeout(name)
            inner()
          }
        }, task.wait)
      }
    }
    inner()
  }

  /**
   * @description: 關(guān)閉某個(gè)定時(shí)器
   * @param {string} name 定時(shí)器名稱
   * @return {*}
   */
  closeTimeout = name => {
    clearTimeout(this[name])
    this[name] = null
  }

  /**
   * @description: 外部調(diào)用關(guān)閉某個(gè)定時(shí)器
   * @param {any} name 定時(shí)器名稱
   * @return {*}
   */
  close = name => {
    try {
      const task = this.tasks.get(name)

      if (task) {
        this.tasks.delete(name)
        this.closeTimeout(name)
        console.log(`%c關(guān)閉定時(shí)器[${name}]成功`, 'color: #24c59d; font-weight: 700')
      } else {
        console.error(`SetInterval => close => 未找到 [${name}] 定時(shí)器`)
      }
    } catch (error) {
      console.error('SetInterval => close => 刪除task失敗 => 失敗原因 => ', error)
    }
  }
}

export default new SetInterval()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容