美文网首页
【观察者模式】和【发布订阅】的区别

【观察者模式】和【发布订阅】的区别

作者: 青城墨阕 | 来源:发表于2022-07-13 15:16 被阅读0次

    参考:https://juejin.cn/post/6978728619782701087

    • 简单实现一个观察者模式
    // 被观察者对象
    class Subject {
        constructor() {
            this.observerList = [];
        }
      
        on(observer) {
            this.observerList.push(observer);
        }
      
        off(observer) {
            this.observerList = this.observerList.filter(o => o !== observer);
        }
      
        emit(message) {
            this.observerList.forEach(o => o.notified(message));
        }
    }
    
    // 观察者
    class Observer {
        constructor(name, subject) {
          this.name = name;
          if (subject) {
            subject.on(this);
          }
        }
      
        notified(message) {
          console.log(this.name, ' got message:', message);
        }
    }
    
    const subject = new Subject();
    const observerA = new Observer('observerA', subject);
    const observerB = new Observer('observerB');
    subject.on(observerB);
    subject.emit('Hello from subject');
    
    subject.off(observerA);
    subject.emit('Hello again');
    
    • 简单实现一个订阅-发布者模式
    // 发布订阅中心
    class PubSub {
        constructor() {
            this.messages = {};
            this.listeners = {};
        }
        publish(type, content) {
            const existContent = this.messages[type];
            if (!existContent) {
                this.messages[type] = [];
            }
            this.messages[type].push(content);
        }
        subscribe(type, cb) {
            const existListener = this.listeners[type];
            if (!existListener) {
                this.listeners[type] = [];
            }
            this.listeners[type].push(cb);
        }
        notify(type) {
            const messages = this.messages[type];
            const subscribers = this.listeners[type] || [];
            subscribers.forEach((cb, index) => cb(messages));
        }
    }
    
    // 发布者
    class Publisher {
        constructor(name, context) {
          this.name = name;
          this.context = context;
        }
        publish(type, content) {
          this.context.publish(type, content);
        }
    }
    
    // 订阅者
    class Subscriber {
        constructor(name, context) {
          this.name = name;
          this.context = context;
        }
        subscribe(type, cb) {
          this.context.subscribe(type, cb);
        }
    }
    
    
    // 使用示例
    const TYPE_A = 'music';
    const TYPE_B = 'movie';
    const TYPE_C = 'novel';
    
    const pubsub = new PubSub();
    
    const publisherA = new Publisher('publisherA', pubsub);
    publisherA.publish(TYPE_A, 'we are young');
    publisherA.publish(TYPE_B, 'the silicon valley');
    const publisherB = new Publisher('publisherB', pubsub);
    publisherB.publish(TYPE_A, 'stronger');
    const publisherC = new Publisher('publisherC', pubsub);
    publisherC.publish(TYPE_C, 'a brief history of time');
    
    
    const subscriberA = new Subscriber('subscriberA', pubsub);
    subscriberA.subscribe(TYPE_A, res => {
      console.log('subscriberA received', res)
    });
    const subscriberB = new Subscriber('subscriberB', pubsub);
    subscriberB.subscribe(TYPE_C, res => {
      console.log('subscriberB received', res)
    });
    const subscriberC = new Subscriber('subscriberC', pubsub);
    subscriberC.subscribe(TYPE_B, res => {
      console.log('subscriberC received', res)
    });
    
    pubsub.notify(TYPE_A);
    pubsub.notify(TYPE_B);
    pubsub.notify(TYPE_C);
    

    相关文章

      网友评论

          本文标题:【观察者模式】和【发布订阅】的区别

          本文链接:https://www.haomeiwen.com/subject/uezxirtx.html