export default class EventChannel {
|
constructor (id, events) {
|
this.id = id
|
this.listener = {}
|
this.emitCache = {}
|
if (events) {
|
Object.keys(events).forEach(name => {
|
this.on(name, events[name])
|
})
|
}
|
}
|
|
emit (eventName, ...args) {
|
const fns = this.listener[eventName]
|
if (!fns) {
|
return (this.emitCache[eventName] || (this.emitCache[eventName] = [])).push(args)
|
}
|
fns.forEach(opt => {
|
opt.fn.apply(opt.fn, args)
|
})
|
this.listener[eventName] = fns.filter(opt => opt.type !== 'once')
|
}
|
|
on (eventName, fn) {
|
this._addListener(eventName, 'on', fn)
|
this._clearCache(eventName)
|
}
|
|
once (eventName, fn) {
|
this._addListener(eventName, 'once', fn)
|
this._clearCache(eventName)
|
}
|
|
off (eventName, fn) {
|
const fns = this.listener[eventName]
|
if (!fns) {
|
return
|
}
|
if (fn) {
|
for (let i = 0; i < fns.length;) {
|
if (fns[i].fn === fn) {
|
fns.splice(i, 1)
|
i--
|
}
|
i++
|
}
|
} else {
|
delete this.listener[eventName]
|
}
|
}
|
|
_clearCache (eventName) {
|
const cacheArgs = this.emitCache[eventName]
|
if (cacheArgs) {
|
for (; cacheArgs.length > 0;) {
|
this.emit.apply(this, [eventName].concat(cacheArgs.shift()))
|
}
|
}
|
}
|
|
_addListener (eventName, type, fn) {
|
(this.listener[eventName] || (this.listener[eventName] = [])).push({
|
fn,
|
type
|
})
|
}
|
}
|