摒弃传统setInterval, 自己封装一个

传统的setInterval在某种情况下会导致内存泄漏,每次调用都会占用一部分内存空间,既然threejs的更新都是基于# requestAnimationFrame的循环调用,那么我们就可以利用这个api,自己封装一个interval循环调用的方法,至于这个api具体怎么用,可以去看一下官网,源码中封装了一个IntervalTime方法,原理就是通过第一次调用时获取高精度时间,和第二次调用的时间相比,如果符合传入的第二个参数“间隔”判断当前是需要执行callback的,方法如下:

export class IntervalTime {
    private intervals: { callback: () => void, time: number, lastTime: number, remainingIterations: number }[] = [];

    constructor() {}

    interval(callback: () => void, time: number, iterations: number = Infinity) {
        this.intervals.push({ callback, time, lastTime: 0, remainingIterations: iterations });
    }

    update() {
        let now = performance.now(); // 使用 performance.now() 获取高精度时间

        for (let i = 0; i < this.intervals.length; i++) {
            const { callback, time, lastTime, remainingIterations } = this.intervals[i];
            let deltaTime = now - lastTime;

            if (deltaTime > time) {
                // 执行一秒内需要做的事情
                callback();
                // 更新剩余执行次数
                this.intervals[i].remainingIterations--;

                if (this.intervals[i].remainingIterations === 0) {
                    // 移除该interval
                    this.intervals.splice(i, 1);
                    i--; // 调整索引以正确处理移除元素后的下一个元素
                } else {
                    // 重置时间
                    this.intervals[i].lastTime = now;
                }
            }
        }
    }

    clearIntervals() {
        this.intervals = [];
    }
}

使用方法如下:

const intervalTime = new IntervalTime();

// 更新时间
intervalTime.interval(() => {
    upDateTime()
}, 1000)

// 更新图表
intervalTime.interval(() => {
    echarts2Draw()
}, 1000 * 5)

// 更新所有序列
intervalTime.update()
posted @ 2024-06-26 10:20  孙凯亮  阅读(1)  评论(0编辑  收藏  举报