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()