Appearance
设计模式
消息订阅与发布
ts
/**
* 事件监听的回调
*/
export type ListenerHandle = (token: string, ...args: any[]) => any;
/**
* 消息订阅发布
*/
export class Pubsub<Token extends string> {
private channels: {
[propName: string]: Function[];
};
constructor() {
this.channels = {};
}
/**
* 事件触发
* @param token 频道名称
* @param args 事件触发时注入的参数
*/
emit(token: Token, ...args: any[]) {
const channel = this.findChannel(token);
if (channel === undefined) {
console.info("无此频道,已经为你创建频道:" + token);
this.addChannel(token);
} else {
channel.forEach((cb) => {
cb(token, ...args);
});
}
}
/**
* 事件监听
* @param token
* @param cb
*/
on(token: Token, cb: ListenerHandle) {
const channel = this.findChannel(token);
if (channel === undefined) {
console.info("无此频道,已经为你先创建此频道" + token);
this.addChannel(token, cb);
} else {
channel.push(cb);
}
}
/**
* 移除某个频道的监听
* @param token 频道id
* @param cb 哪个监听者要被移除
*/
removeOn(token: Token, cb: ListenerHandle) {
const channel = this.findChannel(token);
if (channel) {
if (
!channel.some((ele, index) => {
if (ele === cb) {
channel.splice(index, 1);
console.log(`删除监听者${cb.name}成功!`);
return true;
}
})
) {
console.info("该频道不存在该监听者:" + cb.name);
}
} else {
console.info("不存在该频道:" + token);
}
}
/**
* 移除整个频道
* @param token
*/
remove(token: Token) {
const channel = this.findChannel(token);
if (channel) {
Reflect.deleteProperty(this.channels, token);
} else {
console.info("不存在该频道:" + token);
}
}
/**
* 寻找频道
* @param token 频道id
*/
private findChannel(token: string) {
return Reflect.get(this.channels, token);
}
/**
* 创建频道
* @param token 频道id
* @param cb 回调
*/
private addChannel(token: string, cb?: Function) {
this.channels[token] = cb ? [cb] : [];
return void 0;
}
}
/**
* 默认单实例的PubSub
*/
export const pubsub = new Pubsub<Token>();
/**
* 本次项目所用的token(频道名称)
*/
type Token =
| "user:page-bottom"
| "user:post-comment"
| "user:to-top"
| "window.resize";
/**
* 事件监听的回调
*/
export type ListenerHandle = (token: string, ...args: any[]) => any;
/**
* 消息订阅发布
*/
export class Pubsub<Token extends string> {
private channels: {
[propName: string]: Function[];
};
constructor() {
this.channels = {};
}
/**
* 事件触发
* @param token 频道名称
* @param args 事件触发时注入的参数
*/
emit(token: Token, ...args: any[]) {
const channel = this.findChannel(token);
if (channel === undefined) {
console.info("无此频道,已经为你创建频道:" + token);
this.addChannel(token);
} else {
channel.forEach((cb) => {
cb(token, ...args);
});
}
}
/**
* 事件监听
* @param token
* @param cb
*/
on(token: Token, cb: ListenerHandle) {
const channel = this.findChannel(token);
if (channel === undefined) {
console.info("无此频道,已经为你先创建此频道" + token);
this.addChannel(token, cb);
} else {
channel.push(cb);
}
}
/**
* 移除某个频道的监听
* @param token 频道id
* @param cb 哪个监听者要被移除
*/
removeOn(token: Token, cb: ListenerHandle) {
const channel = this.findChannel(token);
if (channel) {
if (
!channel.some((ele, index) => {
if (ele === cb) {
channel.splice(index, 1);
console.log(`删除监听者${cb.name}成功!`);
return true;
}
})
) {
console.info("该频道不存在该监听者:" + cb.name);
}
} else {
console.info("不存在该频道:" + token);
}
}
/**
* 移除整个频道
* @param token
*/
remove(token: Token) {
const channel = this.findChannel(token);
if (channel) {
Reflect.deleteProperty(this.channels, token);
} else {
console.info("不存在该频道:" + token);
}
}
/**
* 寻找频道
* @param token 频道id
*/
private findChannel(token: string) {
return Reflect.get(this.channels, token);
}
/**
* 创建频道
* @param token 频道id
* @param cb 回调
*/
private addChannel(token: string, cb?: Function) {
this.channels[token] = cb ? [cb] : [];
return void 0;
}
}
/**
* 默认单实例的PubSub
*/
export const pubsub = new Pubsub<Token>();
/**
* 本次项目所用的token(频道名称)
*/
type Token =
| "user:page-bottom"
| "user:post-comment"
| "user:to-top"
| "window.resize";