feng xiaohan

TS 实现发布订阅者模式

// index.ts
interface Event {
  on: (name: string, fn: 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 Event {
  list: List;
  constructor() {
    this.list = {};
  }
  // 注册函数
  on(name: string, fn: Function) {
    const callback = this.list[name] || [];
    callback.push(fn);
    this.list[name] = callback;
    console.log(this.list);
  }
  // 触发函数
  emit(name: string, ...args: Array<any>) {
    let eventName = this.list[name];
    if (eventName) {
      eventName.forEach((fn) => {
        fn.apply(this, args);
      });
    } else {
      console.error(`名称错误${name}`);
    }
  }
  // 删除注册的函数
  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(`名称错误${name}`);
    }
  }
  // 只调用一次函数(设置一个临时函数,使用之后将其删除)
  once(name: string, fn: Function) {
    let del = (...args: Array<any>) => {
      fn.apply(this, args);
      this.off(name, del);
    };
    this.on(name, del);
  }
}

const sp = new Dispatch();

sp.on("post", (...args: Array<any>) => {
  console.log(args, 1); // [1,false,{name:"张三"}] 1
});
sp.once("post", (...args: Array<any>) => {
  console.log(args, "once");
});
const fn = (...args: Array<any>) => {
  console.log(args, 2); // [1,false,{name:"张三"}] 2
};
sp.on("post", fn);

sp.off("post", fn);

sp.emit("post", 1, false, { name: "张三" });