手写发布订阅

66 阅读2分钟

v2-809a23dd4cd0de81fcf03baf240827a3_r.jpg

什么是发布订阅

可以理解成中介和房东和租客的关系,房东把房子推给中介,中介存储下来,如:某个小区,某某房子出租。然后租客找中介说我要某某小区的房子,中介查找查找一遍这个小区有哪些房子在出租,然后带租客一一看了一遍

  • 发布: 房东发布了某小区的房子给中介

  • 订阅: 租客告诉中介我要看哪个小区的房子

const eventHub = {
    // 这个相当于中介的笔记,记录了有哪些小区,哪些房子出租
    queue = {},
    // 这个是发布,可以理解成 房东告诉中介: 我是哪个小区的(name),房子情况如何(fn)
    on: (name, fn) => {
        // 中介看一下记录中有没有这个小区的,没有就加上小区
        eventHub.queue[name] = eventHub.queue[name] || []
        // 加上当前的房子
        eventHub.queue[name].push(fn)
    },
    // 这个是订阅,可以理解成 租客告诉中介,我要某个小区的房子(name)
    emit: (name, params) => {
        // 中介先查一下有没有这个小区的房子要出租,没有就告诉租客说没有
        const p = eventHub.queue[name]
        if (!p) return
        // 如果有,中介就带着租客把这个小区的所有房子一一看一遍
        p.map(f => f.call(undefined, params))
    },
    // 这是注销,这个可以理解为 租客看完房子后,告诉中介某个房子我要了,那中介就找出记录,把这个房子划掉
    off: (name, fn) => {
        // 如果没有这个小区,那么就是租客记错中介了,没啥事了
        const p = eventHub.queue[name]
        if (!p) return
        // 有这个小区,那么去找找是哪个房子,如果没有,那就是租客记错了,没事了
        let index = p.indexOf(fn)
        if (index < 0) return
        // 如果找到了这个房子,那么划掉它,它已经租出去了
        p.splice(index, 1)
    }
}

所以去掉这些注释, 这就是发布订阅的代码

const eventHub = {
    queue = {},
    on: (name, fn) => {
        eventHub.queue[name] = eventHub.queue[name] || []
        eventHub.queue[name].push(fn)
    },
    emit: (name, params) => {
        const p = eventHub.queue[name]
        if (!p) return
        p.map(f => f.call(undefined, params))
    },
    off: (name, fn) => {
        const p = eventHub.queue[name]
        if (!p) return
        let index = p.indexOf(fn)
        if (index < 0) return
        p.splice(index, 1)
    }
}