Open vaakian opened 3 years ago
es6版本,通用参数长度。 且回掉应该异步类型。
class EventEmitter {
callbackMap = new Map();
on(event, fn) {
this.putCallbacks(event, fn);
}
emit(event, ...args) {
const callbacks = this.getCallbacks(event);
callbacks.forEach(fn => {
// emit不要阻塞后续运行
fn instanceof Function && queueMicrotask(() => fn(...args));
})
}
off(event, fn) {
const callbacks = this.getCallbacks(event);
for (let i = 0; i < callbacks.length; i++) {
// 函数引用相同
if (fn === callbacks[i]) {
callbacks.splice(i, 1);
break;
}
}
}
getCallbacks(event) {
const callbacks = this.callbackMap[event];
return Array.isArray(callbacks) ? callbacks : [];
}
putCallbacks(event, fn) {
const callbacks = this.callbackMap[event];
if (Array.isArray(callbacks)) {
callbacks.push(fn);
} else {
this.callbackMap[event] = [fn];
}
}
}
let ob = new EventEmitter();
const sum = (a, b) => {
console.log(a + b);
};
ob.on('sum', sum);
ob.on('multiply', (a, b) => {
console.log(a * b)
})
ob.emit('sum', 5, 6);
ob.emit('multiply', 7, 3)
/*
观察者:`update`
被观察者:`add`,`remove`,`notify`
/*
function Observer(name) {
this.name = name;
}
Observer.prototype.update = function (...args) {
console.log(`${this.name} updated`, args)
}
Observer.prototype.observe = function (observableObject) {
observableObject.add && observableObject.add(this)
}
function Observable() {
this.observers = [];
}
Observable.prototype.add = function (observer) {
this.observers.push(observer)
}
Observable.prototype.notify = function (...args) {
for (let observer of this.observers) {
observer.update(...args)
}
}
Observable.prototype.remove = function (observer) {
for (let i = 0; i < this.observers.length; ++i) {
if (this.observers[i] === observer) this.splice(i, 1)
}
}
let obj = new Observable()
let [lucy, marry] = [new Observer('lucy'), new Observer('marry')]
lucy.observe(obj)
marry.observe(obj)
setTimeout(() => {
obj.notify(1, 2, 3)
}, 200)
``
发布订阅
on添加行为订阅,emit触发该行为。