Skip to content

设计模式-发布订阅

订阅者把想订阅的事件放置到事件中心,当发布者发布该事件的时候,会执行事件中心的所有调度。 vue eventBusVue 双向绑定 redux subscribe

class EventEmitter {
	constructor() {
		this.listener = {}
	}
	// 订阅
	subscribe(eventName, fn) {
		eventName in this.listener
			? this.listener[eventName].push(fn)
			: this.listener[eventName] = [fn]
	}
	offSubscribe(eventName, fn) {
		let cb = this.listener[eventName]
		if (!cb) return 'not eventName'
		const CBCODE = `success offSubscribe ${eventName}`
		if (!fn) {
			this.listener[eventName] = []
			return CBCODE
		}
		for(let i in cb) {
			if (cb[i] == fn || cb[i].fnCallback == fn) {
				cb.splice(i, 1)
				break;
			}
		}
		return CBCODE
	}
	emit(eventName, data) {
		const cb = this.listener[eventName]
		if (!cb) return 'not eventName emit'
		cb.forEach(el => el(data))
	}
	// 单次订阅, 先封装订阅再发布时删除
	once(eventName, fn) {
		const ev = (...arg) => {
			fn(...arg)
			this.offSubscribe(eventName, ev)
		}
		// 自定义值给 off 判断
		ev.fnCallback = fn
		this.subscribe(eventName, ev)

	}
}

MIT License.