基于Typescript 写一个倒计时的基础类

324 阅读2分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情

前言

学习了TypeScript,还不知道灵活使用的可以看一下,下面我分享做一个基于 TypeScript 实现 事件模式的 countdown 基础类(倒计时)的demo来活学活用。

1. 引用事件发布订阅

EventEmitter3 模块是一款经过优化的高性能 EventEmitter,而 EventEmitter 是一种发布/订阅模式的实现方式,通过使用 EventEmitter 我们能够在前端代码中创建自定义的事件机制

emit 触发事件 ; addListener 事件监听

开始,结束倒计时方法时触发事件;计数器的状态发生改变

import { EventEmitter } from 'eventemitter3'

 this.emit(CountdownEventName.START) 

2. ts定义接口,类,函数

interface 定义剩余时间接口

export interface RemainTimeData {
    days: number //天数
    hours: number //小时数 
    minutes: number //分钟数
    seconds: number //秒数
    count: number //毫秒数
}

enum 定义计时器状态枚举

enum CountdownStatus { running, paused, stoped }

字符串枚举 定义计时器事件名称

export enum CountdownEventName { 
START = 'start', 
STOP = 'stop', 
RUNNING = 'running' 
}

组装事件参数Map,通过泛型取参数类型,每一个EventName对应一个参数

interface CountdownEventMap {
    [CountdownEventName.START]: []
    [CountdownEventName.STOP]: []
    [CountdownEventName.RUNNING]: [RemainTimeData, number]
}

3:实现计时器工具类

声明实例的时候开始倒计时方法,自动开启计时器。

export class Countdown extends EventEmitter<CountdownEventMap> {
    private endTime: number
    private remainTime: number = 0 // 剩余时间,初始值是0
    private status: CountdownStatus = CountdownStatus.stoped  // 初始状态是停止的
    private step: number
    
    constructor(endTime: number, step: number = 1e3) { // 结束时间和每多长时间跳动一下
    
        super() // 通过extends一定要super一下
        this.endTime = endTime
        this.step = step
        // 外界声明实例的时候自动开启计时器
        this.start()
    }
    
    // 开始倒计时方法
    public start() {
        this.emit(CountdownEventName.START) 
        this.status = CountdownStatus.running 
        this.countdown() 
    }
    
    // 结束倒计时方法
    public stop() {
        this.emit(CountdownEventName.STOP) 
        this.status = CountdownStatus.stoped 
    }
    
    // 内部运行倒计时方法
    private countdown() {
        if (this.status !== CountdownStatus.running) return
        this.remainTime = Math.max(this.endTime - Date.now(), 0)
        // 内部触发外部的订阅通知
        this.emit(
            CountdownEventName.RUNNING, 
            this.parseRemainTime(this.remainTime), 
            this.remainTime
        )
        // 判断倒计时是否已经结束
        if (this.remainTime > 0) {
            setTimeout(() => this.countdown(), this.step)
        } else { // 如果结束了就结束计时
            this.stop()
        }
    }
    
    // 将时间戳组织成日、时分秒、毫秒
    private parseRemainTime(remainTime: number): RemainTimeData {
        let time = remainTime
        这里的逻辑是利用剩余计算出天,小时,分,秒 然后返回出去
        return { days, hours, minutes, seconds, count }
    }
}

输出格式化返回格式为两位数

export function fillZero(num: number) { return `0${num}`.slice(-2) }

结束语

希望大家能够喜欢我的文章,我真的很用心在写,也希望通过文章认识更多志同道合的朋友。

最后伙伴们,如果喜欢我的可以给点一个小小的赞👍或者关注➕都是对我最大的支持。