学习TypeScript22(实战TS编写发布订阅模式)
概述什么是发布订阅模式,其实小伙伴已经用到了发布订阅模式例如addEventListener,Vue evnetBus都属于发布订阅模式简单来说就是 你要和 大傻 二傻 三傻打球,大傻带球,二傻带水,三傻带球衣。全都准备完成后开始打球。思维导图首先 需要定义三个角色 发布者 订阅者 调度者具体代码on订阅/监听emit 发布/注册once 只执行一次off解除绑定interface EventFa
·
概述
发布订阅模式是一种常见的设计模式,在许多场景中都有应用。我们可能已经在使用中接触过发布订阅模式,比如使用 addEventListener
方法来监听 DOM 事件、Vue 的事件总线机制等。
简单来说,发布订阅模式就像是你和大傻、二傻、三傻一起打篮球。大傻负责带球,二傻负责带水,三傻负责带球衣。只有当他们都准备完成后,才开始打球。
思维导图
首先 需要定义三个角色 发布者 订阅者 调度者
实际案例
- 在 JavaScript 中,我们可以使用 DOM 2 级事件的
addEventListener
方法来订阅和监听事件。 - 在 Electron 中,使用
IpcMain
和ipcRender
来实现主进程和渲染进程之间的事件通信。 - 在 Webpack 中,使用 Hooks 机制来订阅和处理构建过程中的各个阶段。
- 在 Vue 2 中,可以使用事件总线(Event Bus)机制来实现组件之间的通信。
具体代码
on订阅/监听
emit 发布/注册
once 只执行一次
off解除绑定
interface EventFace {
on: (name: string, callback: Function) => void;
emit: (name: string, ...args: Array<any>) => void;
off: (name: string, fn: Function) => void;
once: (name: string, fn: Function) => void;
}
interface List {
[key: string]: Array<Function>;
}
class Dispatch implements EventFace {
list: List;
constructor() {
this.list = {};
}
// 订阅事件
on(name: string, callback: Function) {
const callbackList: Array<Function> = this.list[name] || [];
callbackList.push(callback);
this.list[name] = callbackList;
}
// 发布事件
emit(name: string, ...args: Array<any>) {
let eventName = this.list[name];
if (eventName) {
eventName.forEach(fn => {
fn.apply(this, args);
});
} else {
console.error('该事件未监听');
}
}
// 解除绑定
off(name: string, fn: Function) {
let eventName = this.list[name];
if (eventName && fn) {
let index = eventName.findIndex(fns => fns === fn);
eventName.splice(index, 1);
} else {
console.error('该事件未监听');
}
}
// 一次性订阅
once(name: string, fn: Function) {
let decorator = (...args: Array<any>) => {
fn.apply(this, args);
this.off(name, decorator);
};
this.on(name, decorator);
}
}
const o = new Dispatch();
// 订阅事件 'abc',输出参数和数字 1
o.on('abc', (...arg: Array<any>) => {
console.log(arg, 1);
});
// 一次性订阅事件 'abc',输出参数和字符串 'once',只会触发一次
o.once('abc', (...arg: Array<any>) => {
console.log(arg, 'once');
});
// 发布事件 'abc',输出参数 1、true 和字符串 '小满'
o.emit('abc', 1, true, '小满');
// 再次发布事件 'abc',输出参数 2、true 和字符串 '小满'
o.emit('abc', 2, true, '小满');
更多推荐
已为社区贡献31条内容
所有评论(0)