实现EventHub

在文件1中的f1需要在某种情况下调用文件2中的f2, 用全局变量是不好的,此时可以通过创建一个EventHub,在f1中emit一个事件,然后f2接收到这个事件后,进行相应的操作。
on 和 emit
/src/index.ts
class EventHub {
cache: { [key: string]: Array<(data: unknown) => void> } = {};
// {'报社1':[f1,f2,f3],'报社2':[f11,f22,f33]}
on(eventName: string, fn: (data: unknown) => void) {
// eventName = 报社1, fn
if (this.cache[eventName] === undefined) {
this.cache[eventName] = [];
}
const array = this.cache[eventName];
array.push(fn);
}
emit(eventName:string) {
let array = this.cache[eventName];
if (array === undefined) {
array = [];
}
array.forEach((fn) => {
fn();
});
}
}
export default EventHub;
/test/index.ts
import EventHub from '../src/index';
const eventHub = new EventHub();
let called = false;
eventHub.on('xxx', () => {
console.log('被调用');
called = true;
console.log('called:' + called);
});
eventHub.emit('xxx');
此时called经过eventHub的调用,顺利变为true
class EventHub {
cache: { [key: string]: Array<(data: unknown) => void> } = {};
// {'报社1':[f1,f2,f3],'报社2':[f11,f22,f33]}
on(eventName: string, fn: (data: unknown) => void) {
// eventName = 报社1, fn
this.cache[eventName] = this.cache[eventName] || [];
this.cache[eventName].push(fn);
}
emit(eventName: string, data?: unknown) {
(this.cache[eventName] || []).forEach((fn) => fn(data));
}
}
export default EventHub;
简化emit和on中的逻辑,通常情况下emit中还需传递一个data的参数,我们通过在on中console.assert来断言data的顺利传递
import EventHub from '../src/index';
const eventHub = new EventHub();
const test1 = () => {
eventHub.on('xxx', (y) => {
console.log('被调用');
console.assert(y === 'data1');
});
eventHub.emit('xxx', 'data1');
};
test1()
此时,我们在on中接受的参数!== 'data1',得到了Assertion failed的错误
off操作
/test/index.ts
const test2 = () => {
const eventHub2 = new EventHub();
let called2 = false;
const fn1 = eventHub2.on('yyy', () => {
called2 = true;
});
eventHub2.off('yyy', fn1);
eventHub2.emit('yyy', fn1);
setTimeout(() => {
console.log('--called2---');
console.log(called2);
}, 1000);
};
test2()
创建一个eventHub2,在监听一个事件后,马上取消该事件,called2将不会被修改
/src/index.ts
off(eventName: string, fn) {
// 把fn从this.cache[eventName]中删除
let index;
this.cache[eventName] = this.cache[eventName] || [];
for (let i = 0; i < this.cache[eventName].length; i++) {
if (this.cache[eventName][i] === fn) {
index = i;
break;
}
}
if (index === undefined) {
return;
}
this.cache[eventName].splice(index, 1);
}
我们从cache[eventName]中移除fn方法
此时,我们能从顺利看到called2没有被赋值为true
网友评论