【常见面试题】JS 发布者、订阅者模式

面试中经常出现问到如何实现JS 发布者、订阅者模式。下面是ES5实现发布订阅模式。

1、直接上代码。

javascript 复制代码
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"); // 只执行一次,再次将不再执行

2、如下是打印结果

相关推荐
RoyLin2 分钟前
TypeScript设计模式:仲裁者模式
前端·后端·typescript
子兮曰5 分钟前
🚀前端依赖配置避坑指南:深度解析package.json中devDependencies的常见误解
前端·javascript·npm
瑶琴AI前端6 分钟前
【零成本高效编程】VS Code必装的5款免费AI插件,开发效率飙升!
前端·ai编程·visual studio code
forever_Mamba7 分钟前
实现一个高性能倒计时:从踩坑到最佳实践
前端·javascript
_AaronWong8 分钟前
实现一个鼠标滚轮横向滚动需求
前端·electron
小帆聊前端8 分钟前
JS 原型链深度解读:从混乱到通透,掌握 90% 前端面试核心
javascript
子兮曰8 分钟前
浏览器与 Node.js 全局变量体系详解:从 window 到 global 的核心差异
前端·javascript·node.js
Olrookie9 分钟前
ruoyi-vue(十五)——布局设置,导航栏,侧边栏,顶部栏
前端·vue.js·笔记
召摇10 分钟前
API 设计最佳实践 Javascript 篇
前端·javascript·vue.js
光影少年11 分钟前
vite打包优化有哪些
前端·vite·掘金·金石计划