定时器优化方案

介绍

  1. 为什么会有这个方案:仅仅为了让定时器集中控制,全局有且只有一个定时器。
  2. 如果页面里面有多个定时器的时候可以用以下方案去优化
  3. 如果不想在全局挂载一个无限执行的,只需要自定义开关以下方法。

实现

  1. ts版本
/**
 * 全局增加每秒执行一次定时器功能;(单例+发布订阅模式)
 * @use1 {add} TimeInterval.addEvent(() => {console.log('1s执行一次')});
 * @use2 {add} TimeInterval.addEvent([() => {console.log('3s执行一次')}, 3]);
 * @use3 {delete} TimeInterval.addEvent(a); TimeInterval.deleteEvent(a)
 * @description 自定义几秒执行一次必须为整数!
 * @author lh
 */
type AnyFn = (...arg: any) => any;
type HandleTimeParams = AnyFn | [AnyFn, number]
class HandleTime {
    private number: number = 0;
    private timer: any = null;
    private eventList: HandleTimeParams[] = [];
    install() {
        if (this.timer) return;
        this.timer = setInterval(() => {
            this.number++;
            this.eventList.forEach((content: HandleTimeParams) => {
                if (typeof content === 'function') content?.()
                else {
                    const [fn, nb] = content;
                    this.number % nb === 0 && fn?.();
                }
            })
        }, 1000)
    }
    addEvent(event: HandleTimeParams) {
        this.eventList.push(event)
    }
    deleteEvent(event: HandleTimeParams) {
        const i = this.eventList.findIndex((v: HandleTimeParams) => event === v);
        this.eventList.splice(i, 1)
    }
}
export const TimeInterval = new HandleTime();
TimeInterval.install();
  1. js 版本
/**
 * 全局增加每秒执行一次定时器功能;(单例+发布订阅模式)
 * @use1 {add} TimeInterval.addEvent(() => {console.log('1s执行一次')});
 * @use2 {add} TimeInterval.addEvent([() => {console.log('3s执行一次')}, 3]);
 * @use3 {delete} TimeInterval.addEvent(a); TimeInterval.deleteEvent(a)
 * @description 自定义几秒执行一次必须为整数!
 * @author lh
 */
class HandleTime {
    private number = 0;
    private timer = null;
    private eventList = [];
    install() {
        if (this.timer) return;
        this.timer = setInterval(() => {
            this.number++;
            this.eventList.forEach((content) => {
                if (typeof content === 'function') content?.()
                else {
                    const [fn, nb] = content;
                    this.number % nb === 0 && fn?.();
                }
            })
        }, 1000)
    }
    addEvent(event) {
        this.eventList.push(event)
    }
    deleteEvent(event) {
        const i = this.eventList.findIndex((v) => event === v);
        this.eventList.splice(i, 1)
    }
}
export const TimeInterval = new HandleTime();
TimeInterval.install();

使用

import { TimeInterval } from '@/utils'

// 挂载需要执行的方法
const fn = () => {console.log('1s执行一次')}
TimeInterval.addEvent(fn)
const arrFn = [() => {console.log('3s执行一次')}, 3];
TimeInterval.addEvent(arrFn)
const arrFn10 = [() => {console.log('10s执行一次')}, 10];
TimeInterval.addEvent(arrFn10)

// 卸载(如果离开页面一定要卸载!如果没有用了也要卸载!!!)
setTimeout(() => {
  TimeInterval.deleteEvent(fn)
  TimeInterval.deleteEvent(arrFn)
}, 5)

注意事项

  1. 如果挂载的事件执行完毕了一定要卸载它(调用 deleteEvent方法)避免全局调用无效事件
  2. 挂载是非常简单的,卸载也是非常简单的!但是如果不注意卸载会导致内存泄漏!!!

你可能感兴趣的:(js系列,javascript,前端)