JS 发布者、订阅者模式

2020-05-18  本文已影响0人  SailingBytes

下面是ES5如何实现JS发布订阅模式。

原理在代码中。

function EventEmitter() {

    this.events = {};

};

// 订阅者

EventEmitter.prototype.on = function(ename, callback) {

    if (!this.events[ename]) {

        // 初始化创建订阅,一个订阅名可以创建多个时间函数

        this.events[ename] = [callback];

    } else {

        // 订阅已存在,push指定订阅名称尾部

        this.events[ename].push(callback);

    }

}

// 发布者

EventEmitter.prototype.emit = function(ename) {

    // 遍历执行订阅名称下的所有订阅者事件

    this.events[ename] && this.events[ename].forEach(cb => {

        // 执行订阅者函数

        cb();

    });

}

// 发布者

EventEmitter.prototype.off = function(ename, callback) {

    if (this.events[ename]) {

        // this.events[ename] && this.events[ename].filter(cb => cb != callback)

        // console.log('this.events', this.events)

        const targetIndex = this.events[ename].findIndex(cb => cb === callback)

        if (targetIndex !== -1) {

            this.events[ename].splice(targetIndex, 1)

        }

        if (this.events[ename].length === 0) {

            delete this.events[ename]

        }

    }

}

// 只执行一次订阅发布,然后移除

EventEmitter.prototype.once = function(ename, callback) {

    var that = this;

    var fn = function() {

        callback();

        that.off(ename, fn);

    }

    this.on(ename, fn);

}

// 实例化构造函数

var em = new EventEmitter();

em.on("work", function() {

    console.log('work,订阅发布成功');

});

var makeOnce = function() {

    console.log("money,移除");

}

em.on("money", makeOnce);

em.once("love", function() {

    console.log("love,仅一次");

});

em.emit("work");

em.off("money", makeOnce);

em.emit("money"); // 移除后,无法发布

em.emit("love");

em.emit("love"); // 只执行一次,再次将不再执行

执行发布,打印结果见下图:

上一篇 下一篇

猜你喜欢

热点阅读