美文网首页
观察者和发布订阅模式

观察者和发布订阅模式

作者: 弱冠而不立 | 来源:发表于2021-03-11 23:23 被阅读0次

观察者模式

在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。

当Subject(被观察对象)状态发生变化时,会给所有的Observers(观察者们)发送一个通知函数,观察者们接收到通知后通常会调用各自的更新函数。
代码样例:
const Sub = function(...obrs) {
    // 这个被观察的对象,收录着被哪些观察者观察
    this.obsevers = [...obrs];
}

// 添加观察者关注这个对象
Sub.prototype.add = function(obr) {
    this.obsevers.push(obr)
}

// 被关注的对象,如果更新了就可以调用这个通知方法,去通知所有的观察者去更新
Sub.prototype.notify = function() {
    for(let obr of this.obsevers) {
        if(typeof obr.update === 'function') {
            obr.update();
        }
    }
}

// 例如:

let obj1 = {
    update: () => {
        console.log("update obj1");
    }
}

let obj2 = {
    update: () => {
        console.log("update obj2");
    }
}

// 添加观察者
let sub = new Sub(obj1, obj2);

/** 假设这里有一些操作,使得sub更新了,然后通知所有的观察者去执行它们自己的更新操作 */

// 通知观察者
sub.notify();

发布订阅模式

消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。它们都依托于中间的事件总线。

发布者状态更新时,发布某些类型的通知,而中间控制器只通知订阅了相关类型的订阅者。发布者和订阅者之间是没有直接关联的。
代码样例:
const EventListener = function() {
    this.map = new Map();
}

/**
 * 订阅消息
 * @param {any} e 订阅的消息类型
 * @param {function} fn 订阅后,如果有消息时,需要触发的方法
 */
EventListener.prototype.on = function(e, fn) {

    // 判断是否已经有了订阅的消息类型,有的话就把订阅的方法传入,否则就新建类型
    let eventList = this.map.get(e);
    if(!eventList) {
        this.map.set(e, [fn])
    } else {
        eventList.push(fn);
    }
}

/**
 * 发布消息
 * @param {any} e 订阅的消息类型
 * @param  {...any} arg 发布出去的消息
 */
EventListener.prototype.emit = function(e, ...arg) {

    // 找到发布的消息类型,然后发布消息
    let eventList = this.map.get(e);
    if(eventList) {
       for(let fn of eventList) {
           fn(...arg);
       } 
    } else {
        return false;
    }
}

// 例如

let eventListener = new EventListener();


let user1 = {
    // user1 更新消息后的回调
    update: (...msg) => {
        console.log("课程更新记录:", ...msg);
    }
}

let user2 = {
    // user2 更新消息后的回调
    update: (...msg) => {
        console.log("游戏更新记录:", ...msg);
    }
}

// 分别订阅不同的类型的事件
eventListener.on("class", user1.update)
eventListener.on("game", user2.update)

// 推送不同类型事件的更新消息
eventListener.emit("class", "计算机网络", "毛概")
eventListener.emit("game", "原神")

相关文章

网友评论

      本文标题:观察者和发布订阅模式

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