跳到主要内容

模拟实现

2023年06月11日
柏拉文
越努力,越幸运

一、Vue 方案


class EventBus {
constructor() {
this.events = {};
}
$on(event, fn) {
if (Array.isArray(event)) {
event.forEach((e) => {
this.$on(e, fn);
});
} else {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(fn);
}
}
$off(event, fn) {
if (Array.isArray(event)) {
event.forEach((e) => {
this.$off(e, fn);
});
}
const cbs = this.events[event];
if (!cbs) {
return;
}
if (!fn) {
this.events[event] = null;
}
let cb;
let i = cbs.length;
while (i--) {
cb = cbs[i];
if (cb === fn) {
cbs.splice(i, 1);
break;
}
}
}
$emit(event, ...args) {
let cbs = this.events[event];
if (cbs) {
cbs.forEach((cb) => {
cb.apply(this, args);
});
}
}
$once(event, fn) {
function on() {
this.$off(event, on);
fn.apply(this, arguments);
}
this.$on(event, on);
}
}

测试用例

const eventBus = new EventBus();

function handlerEventA(name) {
console.log("handlerEventA", name);
}
function handlerEventB(name) {
console.log("handlerEventB", name);
}
function handlerEventC(name) {
console.log("handlerEventC", name);
}

eventBus.$on("eventA", handlerEventA);
eventBus.$on("eventB", handlerEventB);
eventBus.$once(["eventA", "eventB"], handlerEventC);

eventBus.$emit("eventA", "eventA - 哈哈");
eventBus.$emit("eventA", "eventA - 嘻嘻");
eventBus.$emit("eventB", "eventB - 哈哈");
eventBus.$emit("eventB", "eventB - 嘻嘻");

二、网上方案


class EventBus {
constructor() {
this.eventObj = {};
this.callbackId = 0;
}
$on(name, callback) {
if (!this.eventObj[name]) {
this.eventObj[name] = {};
}
const id = this.callbackId++;
this.eventObj[name][id] = callback;
return id;
}
$once(name, callback) {
if (!this.eventObj[name]) {
this.eventObj[name] = {};
}
const id = "D" + this.callbackId++;
this.eventObj[name][id] = callback;
return id;
}
$emit(name, ...args) {
const eventList = this.eventObj[name];
for (const id in eventList) {
eventList[id](...args);
if (id.indexOf("D") !== -1) {
delete eventList[id];
}
}
}
$off(name, id) {
delete this.eventObj[name][id];
if (!Object.keys(this.eventObj[name]).length) {
delete this.eventObj[name];
}
}
}

测试用例

const eventBus = new EventBus();

function handlerEventA(name) {
console.log("handlerEventA", name);
}
function handlerEventB(name) {
console.log("handlerEventB", name);
}
function handlerEventC(name) {
console.log("handlerEventC", name);
}

eventBus.$on("eventA", handlerEventA);
eventBus.$on("eventB", handlerEventB);
eventBus.$once(["eventA", "eventB"], handlerEventC);

eventBus.$emit("eventA", "eventA - 哈哈");
eventBus.$emit("eventA", "eventA - 嘻嘻");
eventBus.$emit("eventB", "eventB - 哈哈");
eventBus.$emit("eventB", "eventB - 嘻嘻");