ts轮询类函数方法及案例应用,可配置的时间和次数,开启,停止,重新启动等

本文将介绍如何使用 TypeScript编写一个轮询类。该轮询类支持可配置的轮询时间间隔次数,并且可以通过 startstoprestart 方法来控制轮询的开启、停止和重新启动。最后也会提供使用案例。

核心代码封装:

/**
 * 轮询类封装
  @author xiexikang 2023.6.6 16:33:00
  @param callback:一个回调函数,它会在每一次轮询时被调用。它接收一个数字参数 index,表示当前是第几次轮询。
  @param options:一个可选的配置对象,包含两个属性:
    interval:轮询时间间隔,单位毫秒。
    times:轮询次数,默认为无限次。
  @desc 方法说明:
    start(onStart?):开启轮询。如果已经在进行中,则不会有任何效果。可以传入一个回调函数 onStart,它会在开启轮询时被调用。
    stop(onStop?):停止轮询。如果当前没有进行中的轮询,则不会有任何效果。可以传入一个回调函数 onStop,它会在停止轮询时被调用。
    restart(onRestart?):重新启动轮询。如果当前没有进行中的轮询,则相当于开启新的一次轮询;否则相当于先停止当前的轮询再开启新的一次。可以传入一个回调函数 onRestart,它会在重新启动轮询时被调用。
*/
interface PollingOptions {
  interval: number; // 轮询时间间隔,单位毫秒
  times?: number; // 轮询次数,默认为无限次
}

type PollingCallback = (index: number) => Promise<boolean>;

export default class Polling {
  private timerId: ReturnType<typeof setTimeout> | null = null;
  private count: number = 0;

  constructor(private callback: PollingCallback, private options: PollingOptions) {}
  // 开启轮询
  start(onStart?: () => void): void {
    if (this.timerId !== null) { return; }
    this.count = 0;
    const { interval } = this.options;
    const next = async () => {
      const shouldContinue =
          typeof this.options.times === 'number' ? this.count < this.options.times : true;
      if (!shouldContinue) {
        this.stop();
        return;
      }
      const result = await this.callback(this.count);
      if (!result) {
        this.stop();
        return;
      }
      this.count++;
      this.timerId = setTimeout(next, interval);
    };
    onStart?.();
    next();
  }
  // 停止轮询
  stop(onStop?: () => void): void {
    clearTimeout(this.timerId!);
    this.timerId = null;
    onStop?.();
  }
  // 重新启动轮询
  restart(onRestart?: () => void): void {
    this.stop(() => {
      setTimeout(() => {
        this.start(onRestart);
      }, 0.1e3);
    });
  }
}

如何使用呢? 请看下面案例:目前以vue3作为案例,其他框架自行修改即可使用

  import { reactive, onMounted, onUnmounted } from 'vue';
  import Polling from './polling';
  // 需要轮询的方法
  function fn(index) {
    console.log(`${index + 1} 次轮询`);
  }
  // 轮询信息
  const pollingInfo:Record<string, any> = reactive({
    // 配置
    polling: new Polling(
      async (index) => {
        // return true; // 返回false则停止轮询
        // times:60次
        if (index + 1 === 60) {
          pollingInfo.stop();
          return false;
        }
        fn(index);
        return true;
      },
      { interval: 1000, times: 60 }
    ),
    // 开启
    start() {
      this.polling.start(() => {
        console.log('start');
      });
    },
    // 停止
    stop() {
      this.polling.stop(() => {
        console.log('stop');
      });
    },
    // 重新启动
    restart() {
      this.polling.restart(() => {
        console.log('restart');
      });
    },
  });
  onMounted(() => {
    pollingInfo.start();
  });
  onUnmounted(() => {
    pollingInfo.stop();
  });

在这里插入图片描述