JS手写发布订阅

78 阅读1分钟

使用 Class

class Event {
    constructor() {
        this.eventMap = {}
    }

    // 添加订阅
    on(type, callback) {
        this.eventMap[type] = this.eventMap[type] || []
        this.eventMap[type].push(callback)
    }

    // 发布,执行
    emit(type, ...args) {
        if (!this.eventMap[type]) {
            return
        }
        this.eventMap[type].forEach((item) => {
            item(args)
        })
    }

    // 解除订阅
    off(type, callback) {
        if (!this.eventMap[type]) {
            return
        }
        const index = this.eventMap[type].indexOf(callback);
        if (index < 0) {
            return
        }
        this.eventMap[type].splice(index, 1);
    }

    // 只执行一次
    once(type, callback) {
        // 相当于把这里传进来的 callback 外面再包一层,执行完就从队列里面删除自己
        const fn = (params) => {
            callback(params)
            this.off(type, fn)
        }
        this.on(type, fn)
    }
}

不使用 Class

const eventBus = {
    map: {},
    // 订阅事件
    on: (name, fn) => {
        eventBus.map[name] = eventBus.map[name] || []
        eventBus.map[name].push(fn)
    },
    emit: (name, params) => {
        if (!eventBus.map[name]) { return }
        eventBus.map((item) => {
            item(params)
        })
    },
    off: (name, fn) => {
        if (!eventBus.map[name]) { return }
        const index = eventBus.map[name].indexOf(fn)
        if (index < 0) { return }
        eventBus.map[name].splice(index, 1)
    }
}