手写一个消息的订阅发布

100 阅读2分钟

完成一个建筑工程我们需要哪些步骤呢? 我大概总结下来就是以下几步了:

  1. 需要设计同志设计图纸
  2. 然后需要一线工人根据图纸投入时间经历去建造
  3. 开始运作起来看是否可以正常运行

完成上述之后才算完成了一个完整的工程, 接下来就让我们先从第一步开始吧:

1. 我们需要建立一个消息中心模板, 用以记录 订阅的消息类型 , 订阅消息的人, 发布消息的人, 如下代码所示:

```
class Event {
  constructor () {
    this.eventObject = {}    // 此处用以储存
  }
}
```

2. 在模板中加入订阅系统, 用以统计订阅消息的人其订阅的消息的类型, 当其订阅的消息发布时能及时通知到他消息已发布和发布的具体内容

```
class Event {
  constructor () {
    this.eventObject = {}
  }

  subscribe(eventName, callback) {
    if (this.eventObject[eventName]) {
      this.eventObject[eventName] = [...this.eventObject[eventName], callback]
    } else {
      this.eventObject[eventName] = [callback]
    }
  }
}
```

3. 在模板中加入发布系统, 当有人发布消息时用来通知所有订阅消息的人你订阅的消息已经有人发布了发布者发布的具体内容

```
class Event {
  constructor () {
    this.eventObject = {}
  }

  subscribe(eventName, callback) {
    if (this.eventObject[eventName]) {
      this.eventObject[eventName] = [...this.eventObject[eventName], callback]
    } else {
      this.eventObject[eventName] = [callback]
    }
  }

  publish(eventName, ...args) {
    this.eventObject[eventName].forEach(callback => {
      callback(...args)
    })
  }
}
```

4. 发布系统和订阅系统都有了, 看起来好像已经完善了, 因为我们的主题不就是订阅发布吗? 但是实际上还缺一个, 那就是当订阅者有一天对他订阅的内容不感兴趣了呢, 他需要告知消息中心我不再关注某类消息了, 你如果再推给我我会记得很烦, 综上所述, 我们其实还缺一个退订的系统

```
class Event {
  constructor () {
    this.eventObject = {}
  }

  subscribe(eventName, callback) {
    if (this.eventObject[eventName]) {
      this.eventObject[eventName] = [...this.eventObject[eventName], callback]
    } else {
      this.eventObject[eventName] = [callback]
    }
  }

  publish(eventName, ...args) {
    this.eventObject[eventName].forEach(callback => {
      callback(...args)
    })
  }

  unsubscribe(eventName, callback) {
    if (this.eventObject[eventName]) {
      this.eventObject[eventName] = this.eventObject[eventName].filter(cb => cb !== callback)
    }
  }
}
```

图纸已经画完了, 接下来就到施工步骤了

5. 到现在, 我们的消息中心图纸算是画完了, 接下来就需要照着图示建一个实际的消息中心了

```
const testEvent = new Event()
```

注: 你别说, 建的还挺快的, 这就已经建好了, 哈哈哈哈, 下面就去试试费这么大劲建立的东西靠不靠谱了

终于到最后一步了, 让我们来验证一下成功吧

6. 我现在必须从一个包工头临时变成一个客户了, 现在去订阅一条消息

```
testEvent.subscribe('update', (data) => {
  console.log(data);
})

testEvent.subscribe('get', (data) => {
  console.log(data);
})

testEvent.subscribe('delete', (data) => {
  console.log(data);
})
```

注: 包工头临时cos任务完成了, 就让我们怀着忐忑的心情再去cos一下发布者吧

7. 现在需要cos发布者了, 希望不要出问题吧, 但是也要对自己写的代码有信心啊

```
testEvent.publish('update', 'update')
testEvent.publish('get', 'get')
testEvent.publish('delete', 'delete')
```

微信截图_20230111171505.png

哎呀! 功夫不负有心人, 我的工程圆满结束, 撒花!!!!

注: 如有问题和改进, 欢迎大家积极响应