46. 实现一个发布订阅系统(观察者模式) 副本.md

查看飞书原文 ↗3,653 字符

1. 核心概念 (Core Concept)

发布订阅系统,或称观察者模式 (Observer Pattern),是一种软件设计模式,其中一个对象(称为主题 Subject 或发布者 Publisher)维护一个依赖它的对象列表(称为观察者 Observers 或订阅者 Subscribers),当主题状态发生改变时,会自动通知所有观察者。

2. 为什么需要它? (The "Why")

3. API 与用法 (API & Usage)

实现一个简单的发布订阅系统,通常需要实现以下核心方法:

以下是一个简单的 JavaScript 实现示例:

class EventEmitter {
    constructor() {
        // 用于存储事件类型及其对应的处理函数列表
        this.events = {};
    }

    /**
     * 订阅事件
     * @param {string} eventType 事件类型
     * @param {function} handler 事件处理函数
     */
    subscribe(eventType, handler) {
        if (!this.events[eventType]) {
            this.events[eventType] = [];
        }
        this.events[eventType].push(handler);
    }

    /**
     * 取消订阅事件
     * @param {string} eventType 事件类型
     * @param {function} handler 要移除的事件处理函数
     */
    unsubscribe(eventType, handler) {
        if (!this.events[eventType]) {
            return;
        }
        const index = this.events[eventType].indexOf(handler);
        if (index !== -1) {
            this.events[eventType].splice(index, 1);
        }
    }

    /**
     * 发布事件
     * @param {string} eventType 事件类型
     * @param {...any} args 传递给处理函数的参数
     */
    publish(eventType, ...args) {
        if (!this.events[eventType]) {
            return;
        }
        // 遍历执行所有订阅了该事件的处理函数
        this.events[eventType].forEach(handler => {
            try {
                handler.apply(null, args); // 使用 apply 传递参数
            } catch (e) {
                console.error(`Error in event handler for ${eventType}:`, e);
            }
        });
    }
}

// 示例用法
const emitter = new EventEmitter();

// 定义处理函数
const handler1 = (data) => {
    console.log('Handler 1 received:', data);
};

const handler2 = (msg, value) => {
    console.log('Handler 2 received:', msg, value);
};

// 订阅事件
emitter.subscribe('dataUpdate', handler1);
emitter.subscribe('message', handler2);
emitter.subscribe('message', (msg) => {
    console.log('Handler 3 (anonymous) received:', msg);
});

// 发布事件
console.log('Publishing dataUpdate...');
emitter.publish('dataUpdate', { userId: 123, status: 'online' });

console.log('\nPublishing message...');
emitter.publish('message', 'Hello subscribers!', 42);

// 取消订阅
emitter.unsubscribe('dataUpdate', handler1);

console.log('\nPublishing dataUpdate again...');
emitter.publish('dataUpdate', { newData: true }); // Handler 1 不再收到通知

4. 关键注意事项 (Key Considerations)

5. 参考资料 (References)



原文链接与附件索引