JavaScript中的设计模式:发布-订阅模式
字数 588 2025-11-05 23:47:39

JavaScript中的设计模式:发布-订阅模式

发布-订阅模式(Publish-Subscribe Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。当主题对象状态发生变化时,会通知所有订阅者对象,使它们能够自动更新。

1. 核心概念解析

  • 发布者(Publisher):状态变化时负责发布通知的对象
  • 订阅者(Subscriber):对特定主题感兴趣并注册监听的对象
  • 事件通道(Event Channel):管理订阅关系并传递消息的中间件

2. 基本实现步骤

第一步:创建事件中心(调度中心)

class EventEmitter {
  constructor() {
    this.events = {}; // 存储事件类型和对应的回调函数数组
  }
}

第二步:实现订阅方法(on)

class EventEmitter {
  // ... 构造函数
  
  on(eventName, callback) {
    // 如果事件不存在,创建一个新数组
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    // 将回调函数添加到对应事件的数组中
    this.events[eventName].push(callback);
  }
}

第三步:实现发布方法(emit)

class EventEmitter {
  // ... 之前代码
  
  emit(eventName, ...args) {
    // 获取该事件的所有回调函数
    const callbacks = this.events[eventName];
    if (callbacks) {
      // 依次执行所有回调函数
      callbacks.forEach(callback => {
        callback.apply(null, args);
      });
    }
  }
}

第四步:实现取消订阅方法(off)

class EventEmitter {
  // ... 之前代码
  
  off(eventName, callback) {
    const callbacks = this.events[eventName];
    if (callbacks) {
      // 过滤掉要移除的回调函数
      this.events[eventName] = callbacks.filter(cb => cb !== callback);
    }
  }
}

3. 完整基础实现

class EventEmitter {
  constructor() {
    this.events = {};
  }
  
  on(eventName, callback) {
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(callback);
  }
  
  emit(eventName, ...args) {
    const callbacks = this.events[eventName];
    if (callbacks) {
      callbacks.forEach(callback => callback(...args));
    }
  }
  
  off(eventName, callback) {
    const callbacks = this.events[eventName];
    if (callbacks) {
      this.events[eventName] = callbacks.filter(cb => cb !== callback);
    }
  }
  
  once(eventName, callback) {
    const wrapper = (...args) => {
      callback(...args);
      this.off(eventName, wrapper);
    };
    this.on(eventName, wrapper);
  }
}

4. 使用示例

const eventBus = new EventEmitter();

// 订阅事件
eventBus.on('message', (data) => {
  console.log('订阅者1收到消息:', data);
});

eventBus.on('message', (data) => {
  console.log('订阅者2收到消息:', data);
});

// 发布事件
eventBus.emit('message', 'Hello World!');
// 输出:
// 订阅者1收到消息: Hello World!
// 订阅者2收到消息: Hello World!

// 一次性订阅
eventBus.once('one-time', () => {
  console.log('这个只会执行一次');
});

eventBus.emit('one-time'); // 输出:这个只会执行一次
eventBus.emit('one-time'); // 无输出

5. 高级特性扩展

支持命名空间:

class AdvancedEventEmitter extends EventEmitter {
  on(namespacedEvent, callback) {
    const [eventName, namespace] = namespacedEvent.split('.');
    super.on(eventName, callback);
  }
  
  emit(namespacedEvent, ...args) {
    const [eventName] = namespacedEvent.split('.');
    super.emit(eventName, ...args);
  }
}

6. 实际应用场景

  • DOM事件系统:addEventListener/removeEventListener
  • Vue.js的EventBus:组件间通信
  • Node.js的EventEmitter模块
  • Redux的状态管理
  • WebSocket消息推送

7. 模式优势

  • 解耦:发布者和订阅者不需要知道对方的存在
  • 扩展性:可以方便地添加新的订阅者
  • 灵活性:支持一对多的通信关系

这种模式在前端开发中广泛应用,特别是在组件通信、状态管理等场景中发挥着重要作用。

JavaScript中的设计模式:发布-订阅模式 发布-订阅模式(Publish-Subscribe Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。当主题对象状态发生变化时,会通知所有订阅者对象,使它们能够自动更新。 1. 核心概念解析 发布者(Publisher):状态变化时负责发布通知的对象 订阅者(Subscriber):对特定主题感兴趣并注册监听的对象 事件通道(Event Channel):管理订阅关系并传递消息的中间件 2. 基本实现步骤 第一步:创建事件中心(调度中心) 第二步:实现订阅方法(on) 第三步:实现发布方法(emit) 第四步:实现取消订阅方法(off) 3. 完整基础实现 4. 使用示例 5. 高级特性扩展 支持命名空间: 6. 实际应用场景 DOM事件系统:addEventListener/removeEventListener Vue.js的EventBus:组件间通信 Node.js的EventEmitter模块 Redux的状态管理 WebSocket消息推送 7. 模式优势 解耦:发布者和订阅者不需要知道对方的存在 扩展性:可以方便地添加新的订阅者 灵活性:支持一对多的通信关系 这种模式在前端开发中广泛应用,特别是在组件通信、状态管理等场景中发挥着重要作用。