订阅发布(PubSub)模式的实现以及使用价值

什么是订阅发布模式

订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。

将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相应对象间的一致性,这样会给维护、扩展和重用都带来不便。当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象需要改变时,就可以使用订阅发布模式了。

一个抽象模型有两个方面,其中一方面依赖于另一方面,这时订阅发布模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。订阅发布模式所做的工作其实就是在解耦合。让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。

订阅发布针对前端的使用场景

记得redux是为什么而出现的吗?
就是针对复杂的数据状态的管理,当一个状态发生了变化,你可能要在多个地方更新这些变化,同时这些状态的变化,又会引起其他的状态的变化。
而订阅发布就是解决这样的问题存在的。

有时候,你想监听一种状态,当在某种情况下,触发它,然后做一些相应的事,有点儿类似我们的自定义事件。订阅发布,也是解决这一类问题的利器。

基本的实现

基本的原理是维护一个对象,每次对这个对象进行遍历和更新。

function PubSub() {
    this.handles = {
        eventName: {
            eventsList: [],
            isOne: false,
        }
    }
}
PubSub.prototype.subscribe = function (eventName, callback) {
    let EventsList = [];
    if (arguments.length < 2) {
        throw new TypeError('arguments error');
    }
    if (Reflect.has(this.handles, eventName)) {
        EventsList = this.handles[eventName].eventsList;
    } else {
        this.handles[eventName] = {
            eventsList: [callback],
            isOne: false,
        };
    }
    EventsList.push(callback);
}

PubSub.prototype.notify = function (eventName, ...rest) {
    if (this.handles[eventName]) {
        let EventsList = this.handles[eventName].eventsList, i = 0, isOne = this.handles[eventName].isOne;
        if (EventsList) {
            for (; i < EventsList.length; i++) {
                EventsList[i].apply(this, rest)
            }
        }
        if (isOne) {
            this.unsubscribe(eventName)
        }
    }
    return this;
}

const myPub = new PubSub();

myPub.subscribe('event', function (data) {
    console.log('触发');
    console.log(data)
})
document.getElementById('btn').onclick = function () {
    myPub.notify('event', 123);
}

在npm上如何使用

我在npm发布了关于订阅发布的模块。基本使用如下所示。

import PubSub from 'wd-pub-sub';

// 绑定一个事件名为event的自定义事件
PubSub.subscribe('event', function (data) {
   console.log('触发');
   console.log(data);
});

// 触发事件名为event的自定义事件
PubSub.notify('event', 123);

基本的API如下:

subscribe(eventName, callback);
发布一个自定义的事件

unsubscribe(eventName, callback);
接触一个自定义的事件

subscribeOne(eventName, callback);
发布一个只触发一次的自定义事件

notify(eventName, callback);
触发已经发布的自定义事件

你可能感兴趣的:(插件集成)