isFunction 可以看這篇文章 js判斷參數(shù)類型的實(shí)用工具
import { isFunction } from '@utils/util.type.js'
class SetInterval {
constructor () {
this.tasks = new Map()
}
/**
* @description: 添加定時器方法
* @param {any} name
* @param {async function} callback 必須是異步函數(shù)
* @param {number} wait 等待時間 默認(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名字定時器, 請更換name名 => ${name}`)
return
}
if (!isFunction(callback)) {
console.error('Setinterval => add => callback必須為一個函數(shù)')
return
}
console.log(`%c添加定時器[${name}]成功, 刷新間隔為[${wait}]毫秒, ${leading ? '已' : '未'}開啟先執(zhí)行一次callback功能`, 'color: #24c59d; font-weight: 700')
// 定時器前先執(zhí)行一次函數(shù)
try {
leading && await callback()
} catch (error) {
console.error(`SetInterval => add => 定時器 [${name}] 執(zhí)行出錯, 錯誤原因 => ${error}`, 'color: #24c59d; font-weight: 700')
}
this.tasks.set(name, { wait, callback })
this.run(name)
}
/**
* @description: 將定時任務(wù)添加到隊(duì)列中
* @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}] 執(zhí)行出錯, 錯誤原因 => ${error}`)
} finally {
this.closeTimeout(name)
inner()
}
}, task.wait)
}
}
inner()
}
/**
* @description: 關(guān)閉某個定時器
* @param {string} name 定時器名稱
* @return {*}
*/
closeTimeout = name => {
clearTimeout(this[name])
this[name] = null
}
/**
* @description: 外部調(diào)用關(guān)閉某個定時器
* @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關(guān)閉定時器[${name}]成功`, 'color: #24c59d; font-weight: 700')
} else {
console.error(`SetInterval => close => 未找到 [${name}] 定時器`)
}
} catch (error) {
console.error('SetInterval => close => 刪除task失敗 => 失敗原因 => ', error)
}
}
}
export default new SetInterval()