实现发布订阅

121 阅读1分钟
class EventEmitter {
    constructor(options = {}) {
        this.events = {}
        this.maxListener = options.maxListener || Infinity
    }
    emit(event, ...args) {
        const cbs = this.events[event]
        if (!cbs) return this
        cbs.forEach(fn => fn.apply(this, args));
        return this
    }
    on(event, cb) {
        if (!this.events[event]) this.events[event] = []
        if (this.maxListener !== Infinity && this.events[event].length >= this.maxListener) {
            console.warn(`${event} has reached max listeners`);
            return this
        }
        this.events[event].push(cb)
        return this
    }
    once(event, cb) {
        let self = this
        function fn(...args) {
            self.off(event, fn)
            cb.apply(self, args)
        }
        this.on(event, fn)
        return this
    }
    off(event, cb) {
        if (!cb) {
            this.events[event] = null
        } else {
            this.events[event] = this.events[event].filter(fn => fn !== cb)
        }
        return this
    }
}

const add = (a,b) => console.log(a+b);
const log = (...arg) => console.log(...arg);
const event = new EventEmitter({maxListener: 3})
event.on('add', add)
event.on('add', add)
event.on('add', add)
event.on('add', add)
event.on('log', log)
event.emit('add', 1,2)
event.emit('log', 'hello~')
event.once('one', value => console.log(value))
event.emit('one', '第一次~')
event.emit('one', '第二次~')