发布订阅 是一种很常用的设计模式,这个设计模式的好处是,发送端和接收端 都不会受到 对方所写的其他逻辑所 干扰。只需要双方约定好 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) // 订阅