vaakian / vaakian.github.io

some notes
https://vaakian.github.io
3 stars 0 forks source link

手写EventEmitter #28

Open vaakian opened 2 years ago

vaakian commented 2 years ago

简单,就是发布订阅模式。 深信服面试考到了,索性再温习一遍,又有新的收获。 通过Symbol.for来保证key唯一,来标记once

class EventEmitter {
    eventHandlers = {}
    on(event, fn) {
        let { eventHandlers } = this
        if (typeof eventHandlers[event] === 'undefined') eventHandlers[event] = [fn]
        else eventHandlers[event].push(fn)
    }
    emit(event, data) {
        let handlers = this.eventHandlers[event] || []
        for (let handler of handlers) {
            handler(data)
            // 触发一次就清掉
            if (handler[Symbol.for('isOnce')] === true) this.off(event, handler)
        }
    }
    once(event, fn) {
        this.on(event, fn)
        fn[Symbol.for('isOnce')] = true
    }
    off(event, fn) {
        let handlers = this.eventHandlers[event] || []
        for (let i = 0; i < handlers.length; ++i) {
            if (handlers[i] === fn) handlers.splice(i, 1)
        }

    }
    clear() {
        this.eventHandlers = {}
    }
}

let work = new EventEmitter()

work.on('up', function (data) {
    console.log(`${data} 上班啦!`)
})
work.once('notify', function (data) {
    console.log(`once notify ${data}`)
})

work.emit('notify', 'hello!')
work.emit('notify', 'world!')

let testFn = (data) => {
    console.log(`test off ${data}`)
}
work.on('off', testFn)
work.emit('off', 'OFF!')
work.off('off', testFn)
work.emit('off', 'OFF AGAIN!')
for (let person of ['Lucy', 'Allen', 'Jack']) {
    work.emit('up', person)
}