最简单的发布订阅模式:
const listeners = [];
// 订阅事件
export const on = (fn) => {
listeners.push(fn);
}
// 发布事件
export const emit = () => {
listeners.forEach(f => f());
}
实现简易的 tapable :
type TapEvent = string;
type Handler = () => void;
type EventCenter = Record<TapEvent, Handler>;
interface IHook {
tap: (name: TapEvent, func: Handler) => void;
call: (name?: TapEvent) => void;
}
class SyncHook implements IHook {
private events: EventCenter
constructor() {
this.events = {};
}
// 订阅事件
public tap(name: TapEvent, func: Handler) {
this.events[name] = func;
}
// 发布事件
public call(name?: TapEvent) {
if (
name &&
Object.prototype.hasOwnProperty.call(this.events, name)
) {
this.events[name]();
} else {
Object.values(this.events).forEach(f => f());
}
}
}
const hook = new SyncHook();
hook.tap("make", () => console.log("event:%s", "make"));
hook.tap("emit", () => console.log("event:%s", "emit"));
hook.tap("done", () => console.log("event:%s", "done"));
hook.call();