🤔️要求
要求实现一个 EventEmitter 类,该类中存在两个方法 on / emit。on(functionName, function)
方法可以订阅一个 functionName 的函数。emit(functionName, ...args)
方法可以调用 on 方法中注册的函数,获得对应的函数类型
const eventEmitter = new EventEmitter();
eventEmitter.on('sayHello', (name: string) => {
console.log(name);
})
eventEmitter.on('sayAge', (age: number) => {
console.log(name);
})
eventEmitter.emit('sayHello', 'test') // expect success
eventEmitter.emit('hello', 'test') // expect error, 函数名没有被注册
eventEmitter.emit('sayHello', 123) // expect error, sayHello 的参数类型为 string
eventEmitter.emit('sayHello', 'test', '124') // expect error, sayHello 的参数数量为1
📖知识点
🔗知识链接
😢问题 & 解答
🍗场景
// 实现一个 eventEmitter 类
class EventEmitter<T extends Record<string, unknown[]>> {
private fnMap = new Map<keyof T, (...args: any) => void>();
on<K extends keyof T>(key: K, fn: (...args: T[K]) => void): void {
this.fnMap.set(key, fn);
}
emit<K extends keyof T>(key: K): (...args: T[K]) => void {
const fn = this.fnMap.get(key);
return (...args: T[K]) => {
fn && fn(...args);
};
}
}
const eventEmitter = new EventEmitter<{
sayName: [string],
sayAge: [number],
}>();
eventEmitter.on('sayName', (name: string) => {
console.log(name)
});
eventEmitter.emit('sayName')('name');
eventEmitter.on('sayAge', (age: number) => {
console.log(age)
});
eventEmitter.emit('sayAge')(88);