实现自己想要的Emitter
对于注册事件这个过程,我们分别想在以下节点做一些事情:
- 第一次有注册监听的时
- 第一次监听注册成功时
- 当有监听被注册时
- 所有监听移除时
同时我们需要它具有如下能力:
- 一次性移除所有监听(而不是我们自己一个一个
removeEventListener
) - 移除单个
listener
因此,我们设计了如下结构:
export interface EmitterOptions {
onFirstListenerAdd?: Function; // 第一次注册监听回调
onFirstListenerDidAdd?: Function; // 低一次注册监听完成回调
onListenerDidAdd?: Function; // 当有事件被监听成功
onLastListenerRemove?: Function; // 当最后一个事件被移除
}
export class Emitter<T> {
private readonly _options?: EmitterOptions; // 事件触发器选项,在事件添加监听和移除时候,相关节点,暴露出来,比如:第一个监听被添加、最后一个监听被移除。
private _disposed: boolean = false; // 此事件桥是否已经释放
private _event?: Event<T>; // 返回一个事件注册函数
protected _listeners?: LinkedList<Listener<T>>; // 事件监听
constructor(options?: EmitterOptions) {
this._options = options;
}
// 获取“emitter.on”函数
get event(): Event<T> {
...
}
// 相当于:emitter.emit
fire(event: T): void {
...
}
// 解除所有监听
dispose() {
...
}
}
首先,关于event
(on函数)的实现如下(详细的函数会放最下面,有需要的看下即可):
get event(): Event<T> {
// 相当于emitter.on
if (!this._event) {
// 不存在"on"函数,则创建一个并返回
this._event = (listener: (e: T) => any, thisArgs?: any) => {
this.initListeners(); // 初始化listeners 集合
const firstListener = this._listeners.isEmpty();
this.onFirstListenerAdd();// 当第一个listener被添加的时候,执行回调。
const remove = this._listeners.push(!thisArgs ? listener : [listener, thisArgs]); // 加入listener,并且返回一个删除改listener的函数。
this.onFirstListenerDidAdd();// 第一个listener被添加完成,执行回调
this.onListenerDidAdd();// 当有listener被添加,执行回调
return this.eventDispose(remove); // 返回解除此事件的函数
}
}
return this._event;
}
其次,关于fire
(emit函数)函数的实现如下:
fire(event: T): void {
if (this._listeners) {
while (this._listeners.size > 0) {
const listener = this._listeners.shift()!;
try {
if (typeof listener === 'function') {
listener.call(undefined, event);
} else {
listener[0].call(listener[1], event);
}
} catch (e) {
console.log(e);
}
}
}
}
最后,关于dispose
函数实现:
dispose() {
if (this._listeners) {
this._listeners.clear();
}
this._disposed = true;
this.onLastListenerRemove();
}
至此,我们实现了一个自己的Emitter
, 我们来使用看看:
const emitter = new Emitter({
onFirstListenerAdd: () => console.log('onFirstListenerAdd');
onFirstListenerDidAdd: () => console.log('onFirstListenerDidAdd');
onListenerDidAdd: () => console.log('onListenerDidAdd');
onLastListenerRemove: () => console.log('onLastListenerRemove');
});
const listener1 = emitter.event(() => console.log('这是我们的自己的监听回调-1')); // fire时候,则会执行回调
const listener2 = emitter.event(() => console.log('这是我们的自己的监听回调-2')); // fire时候,则会执行回调
listener1.dispose(); // 移除监听1
// emitter.dispoase(); 移除所有监听
emitter.fire(); // 触发事件
ps: 上述过程中使用到的一些具体实现:
private initListeners() {
if (!this._listeners) {
this._listeners = new LinkedList();
}
}
private onFirstListenerAdd(firstListener: Listener) {
if (firstListener && this._options && this._options.onFirstListenerAdd) {
this._options.onFirstListenerAdd(this);
}
}
private onFirstListenerDidAdd(listener: Listener) {
if (firstListener && this._options && this._options.onFirstListenerDidAdd) {
this._options.onFirstListenerDidAdd(this);
}
}
private onListenerDidAdd(listener: Listener) {
if (this._options && this._options.onListenerDidAdd) {
this._options.onListenerDidAdd(this, listener, thisArgs);
}
}
private onLastListenerRemove() {
if (this._options && this._options.onLastListenerRemove) {
const hasListeners = (this._listeners && !this._listeners.isEmpty());
if (!hasListeners) {
this._options.onLastListenerRemove(this);
}
}
}
private eventDispose(remove: function) {
return {
dispose: () => {
if (!this._disposed) {
remove();
this.onLastListenerRemove();
}
}
}
}
这个emitter
有啥用呢,请听下回分解:如何给ipcMain赋予我们自己实现的Emitter的能力