模拟setInterval实现暂停和重启的功能
/** timer.ts */
export default class Timer {
/** 间隔时间 */
private interval: number;
private timeout: NodeJS.Timeout | null;
/** 定时器的运行状态 */
public running: boolean;
/** 回调函数 */
private callback: () => void;
constructor(interval: number, callback: () => void) {
this.interval = interval;
this.timeout = null;
this.running = false;
this.callback = callback;
}
// 定时器开始
public start(): void {
if (this.running) return;
this.running = true;
this.run(); // 直接调用run,而不是setTimeout,run方法中会自己处理setTimeout逻辑
}
// 执行定时器
public run(): void {
if (!this.running) return;
console.log('执行任务 ...', this.timeout);
this.callback();
if (this.timeout) {
clearTimeout(this.timeout); // 清除前一个timeout以免重复
}
this.timeout = setTimeout(() => this.run(), this.interval);
}
// 暂停/停止定时器
public stop(): void {
if (this.timeout) {
clearTimeout(this.timeout);
}
console.log('暂停任务 ...', this.timeout);
this.running = false;
}
// 暂停后恢复定时器
public resume(): void {
if (this.running || this.timeout === null) return;
console.log('重启任务 ...');
this.running = true;
this.run();
}
}
功能实现
<template>
<a-button class="ml-5" @click="startInterval()">
<template #icon><icon-play-arrow-fill /></template>
启动
</a-button>
<a-button v-if="isPaused" class="ml-5" @click="pauseInterval()">
<template #icon><icon-pause-circle-fill /></template>
暂停
</a-button>
<a-button v-if="!isPaused" class="ml-5" @click="resumeInterval()">
<template #icon><icon-refresh /></template>
重启
</a-button>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import Timer from '@/utils/timer';
const isPaused = ref();
const startInterval = () => {
isPaused.value = true;
timer.start();
};
// 重启计时器
const resumeInterval = () => {
isPaused.value = true;
timer.resume();
};
// 暂定计时器
const pauseInterval = () => {
isPaused.value = false;
timer.stop();
};
</script>
实现效果