发布订阅模式(观察者模式)

发布订阅模式(观察者模式)

发布订阅也叫观察者模式

发布 && 订阅

// 观察者模式(发布订阅)
// 发布者
class Publisher {
    /**
     * 构造函数:
     * 定义一个存放所有观察者的数组
     */
    constructor() {
        this.subs = [];
    }

    /**
     * 判断是否是 Subscriber 类的实例
     * @param {*} subscriber 
     */
    isSubscriber(subscriber) {
        return subscriber instanceof Subscriber;
    }
    
    /**
     * 添加订阅者
     * @param {*} Subscriber 
     */
    addSubscriber(Subscriber) {
        if (!this.isSubscriber(Subscriber)) {
            throw new Error("The parameter is must be instanceof Subscriber");
        }
        this.subs.push(Subscriber);
    }

    /**
     * 移除订阅者
     * @param {*} Subscriber 
     */
    removeSubscriber(Subscriber) {
        if (!this.isSubscriber(Subscriber)) {
            throw new Error("The parameter is must be instanceof Subscriber");
        }
        this.subs.forEach((item, index) => {
            if (item === Subscriber) {
                this.subs[index] = null;
            }
        });
    }

    /**
     * 通知所有订阅者执行
     * @param  {...any} args 
     */
    notify(...args) {
        this.subs.forEach(item => {
            if (this.isSubscriber(item)) {
                item.exec(...args)
            }
        });
    }
}

// 订阅者
class Subscriber {
    /**
     * 构造函数:
     * 在初始化实例的时候必须传入一个函数
     * 将这个函数fn挂载到实例上
     * @param {*} fn 
     */
    constructor(fn) {
        if (typeof fn !== "function") {
            throw new Error("The parameter is must be function");
        }
        this.fn = fn;
    }

    /**
     * 确保每个实例都有一个exec方法
     * 在发布者通知执行的时候执行实例上的fn方法
     */
    exec() {
        this.fn();
    }
}

使用

const publisher = new Publisher();
const w1 = new Subscriber(function () {
    console.log(1);
});
const w2 = new Subscriber(function () {
    publisher.removeSubscriber(w1);
    console.log(2);
});
const w3 = new Subscriber(function () {
    console.log(3);
});

publisher.addSubscriber(w1);
publisher.addSubscriber(w2);
publisher.addSubscriber(w3);

publisher.notify(); // 1 2 3
console.log("------------");
publisher.notify(); // 2 3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值