基于typescript 写一个发布订阅 event

本文深入探讨了TypeScript中实现的发布订阅模式,这是一种常用的设计模式,能够有效地解耦发送者与接收者,使得双方仅需关注事件的属性值即可进行通信。文章详细介绍了如何在TypeScript中定义事件键、使用接口约束方法以及实现发布订阅接口,同时对比了JavaScript的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发布订阅 是一种很常用的设计模式,这个设计模式的好处是,发送端和接收端 都不会受到 对方所写的其他逻辑所 干扰。只需要双方约定好 eventemit中的属性值就可以了

设计模式是一种设计方式,目的是让人更好更优的去实现程序中复杂的逻辑关系。目的不在意于用什么语言去实现、

这里 会说一下 js和ts是怎么实现的,但重点会在 ts中

首先:ts是 可以直接编译成 js的,所以我们这里先 写 ts的  js的等编译完了就会生成了

一:想定义一下 key属性,这样写的好处就是可以直接在此处 添加key,开发双方都需要保持这个key,当然也可以再次出做一个封装,然其使用起来更安全更便于修改。但这不是发布订阅的 核心

export enum EventKeys {
  MSG = 'msg',
  GRO = 'groupResDataObj'
}

二 使用接口约束一下发布订阅的 方法


interface Events {
  OnEvent(key: string, fn: Function): void,
  EmitEvent(keys: string, msg?: unknown): void,
  RemoveEvent(key: string, fn: Function): void
}

三 就是去实现发布订阅的接口

    注意这里的 list :在js中  这里仅仅 是  list={}  但在ts中 需要 定义其 结构

   其实 js中 最后 也是

let list = {
  'key':function
}
class EventEmit implements Events {
  private list: { [key: string]: Function[] } = {}
  /**
   * 订阅模块
   * @param key 
   * @param fn 
   */
  OnEvent(key: string, fn: Function) {
    if (!this.list[key]) {
      this.list[key] = []
    }
    this.list[key].push(fn)
  }

  /**
   * 发布模块
   */
  EmitEvent(key: string, msg?: any) {
    let fns = this.list[key]
    if (!fns || fns.length === 0) return false
    fns.forEach(cd => { cd(msg) })
  }

  /**
   * 取消订阅
   * @param key  
   * @param fn 
   */
  RemoveEvent(key: string, fn: Function) {
    let fns = this.list[key]
    if (!fns) return false
    if (!fn) {
      fns && (fns.length = 0)
    } else {
      fns.forEach((cd: Function, i: number) => {
        if (cd === fn) {
          fns.splice(i, 1)
        }
      })
    }
  }
}

此时 还需要对 ts做一个 对外暴露

export var EventFn = new EventEmit()

这样 我们的ts 发布订阅就完成了  我们在编译看看  生成的js如下,

var EventEmit = /** @class */ (function () {
    function EventEmit() {
        this.list = {};
    }
    /**
     * 订阅模块
     * @param key
     * @param fn
     */
    EventEmit.prototype.OnEvent = function (key, fn) {
        if (!this.list[key]) {
            this.list[key] = [];
        }
        this.list[key].push(fn);
    };
    /**
     * 发布模块
     */
    EventEmit.prototype.EmitEvent = function (key, msg) {
        var fns = this.list[key];
        if (!fns || fns.length === 0)
            return false;
        fns.forEach(function (cd) { cd(msg); });
    };
    /**
     * 取消订阅
     * @param key
     * @param fn
     */
    EventEmit.prototype.RemoveEvent = function (key, fn) {
        var fns = this.list[key];
        if (!fns)
            return false;
        if (!fn) {
            fns && (fns.length = 0);
        }
        else {
            fns.forEach(function (cd, i) {
                if (cd === fn) {
                    fns.splice(i, 1);
                }
            });
        }
    };
    return EventEmit;
}());
exports.EventFn = new EventEmit();

上面的是原生的js写法  我们也可以居于  es6写 js

class EvnetEmit {
  list = {}
  OnEvent (key, fn) {
    if (this.list[key]) {
      this.list[key] = []
    }
    this.list[key].push(fn)
  }

  EmitEvent (key, msg) {
    let fns = this.list[key]
    if (!fns || fns.length === 0) return false
    fns.forEach(cb => cb(msg))
  }

  RemoveEvent (key, fn) {
    var fns = this.list[key];
    if (!fns) return false;
    if (!fn) {
      fns && (fns.length = 0);
    }else {
      fns.forEach(function (cd, i) {
        if (cd === fn) {
          fns.splice(i, 1);
        }
      });
    }
  }
}

至此  简单的发布订阅 就 在ts和js中实现了  接下来就是  使用了

evnets.EmitEvent(key,msg) // 发布的
events.OnEvent(key,function) // 订阅

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值