【常见面试题】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、如下是打印结果

相关推荐
郭老二6 小时前
【前端】vue3:编译步骤
前端
不在逃避q7 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁7 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9857 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易7 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师8 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174469 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈9 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen10 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒10 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端