最近重新注意到node是由事件驱动的,所以主要看了下官网的EventEmitter,发现貌似实现起来很简单,于是简单重写了下,只是实现了几个比较重要的方法
class MyEmitter {
constructor() {
this.eventsMap = {};
}
on(event, callback) {
if (typeof callback !== "function") throw new Error("传函数");
this.eventsMap[event] = {
isOnce: false,
callback,
};
}
emit(event, ...args) {
const { isOnce, callback } = this.eventsMap[event] || {};
if (isOnce) delete this.eventsMap[event];
try {
callback.apply(this, args);
} catch (error) {
const { callback: errorHandler } = this.eventsMap["error"] || {};
if (!errorHandler) throw new Error(error);
errorHandler.call(this, error);
}
}
once(event, callback) {
if (typeof callback !== "function") throw new Error("传函数");
this.eventsMap[event] = {
isOnce: true,
callback,
};
}
}
测试案例:
const myEmitter = new MyEmitter();
myEmitter.on("work", () => {
console.log("work daily");
});
myEmitter.on("play", function (thing, someone) {
console.log(`i am playing ${thing} with ${someone}`);
console.log(this);
});
myEmitter.on("error", function (error) {
console.log(`${Date.now()} - ${error.message}`);
});
let count = 0;
myEmitter.once("add", function (thing, someone) {
console.log(++count);
});
//同步执行
myEmitter.emit("work");
myEmitter.emit("work");
myEmitter.emit("play", "basktball", "cxk");
myEmitter.emit("add");
myEmitter.emit("add");
跑出来的结果如下:
work daily
work daily
i am playing basktball with cxk
MyEmitter {
eventsMap: {
work: { isOnce: false, callback: [Function] },
play: { isOnce: false, callback: [Function] },
error: { isOnce: false, callback: [Function] },
add: { isOnce: true, callback: [Function] }
}
}
1
1635074408913 - Cannot read property 'apply' of undefined