返回首页

观察者与发布订阅(面试版)

一、面试常考点

1. 两者核心区别

观察者是“直接依赖”;发布订阅是“通过事件中心解耦”。

2. 为什么容易混淆

两者都体现“一对多通知”,但依赖关系不同。

3. 面试追问点

事件中心如何防止内存泄漏、如何做一次订阅与解绑。

二、细节介绍

1. 观察者模式

Subject 持有 Observer 列表,状态变化时直接通知。

2. 发布订阅模式

Publisher 和 Subscriber 不直接耦合,由 EventBus 转发消息。

3. 工程侧注意

事件监听必须可解绑,否则容易造成重复触发和内存泄漏。

三、示例代码

class EventBus {
  constructor() {
    this.events = new Map()
  }

  on(eventName, handler) {
    const arr = this.events.get(eventName) || []
    arr.push(handler)
    this.events.set(eventName, arr)
    return () => this.off(eventName, handler)
  }

  off(eventName, handler) {
    const arr = this.events.get(eventName) || []
    this.events.set(
      eventName,
      arr.filter((fn) => fn !== handler)
    )
  }

  emit(eventName, payload) {
    const arr = this.events.get(eventName) || []
    arr.forEach((fn) => fn(payload))
  }
}

const bus = new EventBus()
const cancel = bus.on('order.created', (data) => {
  console.log('send email:', data.id)
})

bus.emit('order.created', { id: 'A1001' })
cancel()

四、常用应用场景

1. 前端事件总线

跨组件通信(中小项目)。

2. 业务异步通知

下单后通知库存、物流、消息中心。

3. 系统监控

状态变化广播给日志、埋点、告警模块。

五、高频追问标准答法(Q/A)

1. Q: 观察者和发布订阅一句话区别

A: 观察者是主体直接通知观察者;发布订阅通过事件中心中转,解耦更强。

2. Q: 事件总线常见问题

A: 不解绑导致内存泄漏、事件名冲突、事件链难追踪。

3. Q: 如何避免事件系统失控

A: 事件命名分层、强制解绑、关键事件埋点、减少全局泛滥广播。