发布订阅模式:

定义对象间一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
事件总线是对发布订阅模式的一种实现,也是一种集中式事件处理机制,允许不同组件之间相互通信,而不需要相互依赖,以此来解耦
应用场景:公众号消息,短信提醒等等

传统的事件总线和发布订阅的实现
事件总线
const eventBus = {
// 保存类型和回调容器
callbacks: {
// login: [fn1, fn2]
}
};

// 绑定事件
eventBus.on = function (eventName, callback) {
// 判断有该类型事件
if (this.callbacks[eventName]) {
// 推入
this.callbacks[eventName].push(callback);
} else {
// 构造该类型数组
this.callbacks[eventName] = [callback];
}
};

// 触发事件
eventBus.emit = function (eventName, data) {
// 判断有该类型事件
if (this.callbacks[eventName]?.length > 0) {
// 遍历数组里函数执行传入数据
this.callbacks[eventName].forEach(event => event(data));
}
};

eventBus.off = function (eventName) {
// 如果传入事件名
if (eventName) {
// 删除指定事件
delete this.callbacks[eventName];
} else {
// 清空
this.callbacks = {};
}
};

// 测试
eventBus.on(“login”, data => {
console.log(用户已经登陆,数据${data});
});

eventBus.on(“logout”, data => {
console.log(用户已经退出,数据${data});
});

setTimeout(() => {
eventBus.emit(“login”, “云牧”);
eventBus.emit(“logout”, “云牧”);
}, 1000);

// eventBus.off(“login”);
// eventBus.off();
复制代码
发布订阅
const PubSub = {
id: 1,
callbacks: {
// pay:{
// // token_1: fn1,
// // token_2: fn2,
// }
}
};

PubSub.subscribe = function (channel, callback) {
// 唯一的编号
let token = “token_” + this.id++;
// 判断callbacks是否存在channel
if (this.callbacks[channel]) {
// 存入
this.callbacks[channel][token] = callback;
} else {
// 构造出对象存入
this.callbacks[channel] = {
[token]: callback
};
}
return token;
};

// 订阅频道
PubSub.publish = function (channel, data) {
// 获取当前频道所有的回调 遍历执行
if (this.callbacks[channel]) {
Object.values(this.callbacks[channel]).forEach(callback => callback(data));
}
};

// 取消订阅
PubSub.unsubscribe = function (flag) {
// 没有传则全部清空
if (!flag) {
this.callbacks = {};
// 判断
} else if (typeof flag === “string”) {
// 如果包含token_
if (flag.includes(“token_”)) {
// 遍历对象找到对应token
const callbackobj = Object.values(this.callbacks).find(obj => obj.hasOwnProperty(flag));
if (callbackobj) {
delete callbackobj[flag];
}
} else {
// 删除该订阅下所有回调
delete this.callbacks[flag];
}
}
};

// 测试
const id1 = PubSub.subscribe(“pay”, data => {
console.log(“商家接受到了订单”, data);
});
const id2 = PubSub.subscribe(“pay”, data => {
console.log(“骑手接受到了订单”, data);
});
const id3 = PubSub.subscribe(“cancel”, data => {
console.log(“买家取消了订单”, data);
});

// 取消了id1,商家无法接到订单
PubSub.unsubscribe(id1);

PubSub.publish(“pay”, {
title: “鱼香肉丝”,
price: 20,
address: “xxx”
});
PubSub.publish(“cancel”, {
title: “鱼香肉丝”,
price: 20,
address: “xxx”
});

四行实现发布订阅

原理:
表面是 window,根本是 EventTarget,window、document 和元素节点都是继承于 EventTarget
XMLHttpRequest、 WebSocket 也继承于 EventTarget
继承于它,就可以实现事件中心,可以 EventTarget.addEventListener() 、 EventTarget.removeEventListener() 、EventTarget.dispatchEvent
简化三行

升级八行
上面三行实现有诸多问题,比如不能多个实例、不能传递多参数、参数从 e.detail 获取不合理等
改进如下:

自定义事件
内置事件类型

点击按钮,这是 click 事件
输入框失焦,这是 blur 事件
鼠标滚动,这是 wheel 事件

触发内置事件

element[eventType] 直接调用
new [Event] + dispatchEvent

document.createElement(“a”).click();

// 自定义事件触发
const event = new MouseEvent(“click”);

document.createElement(“a”).dispatchEvent(event);

前端快捷生成 uuid
URL.createObjectURL(new Blob([“”])).split(“/”).pop()

自定义事件三种方式

document.createEvent()(废弃)

new Event()

new CustomEvent()

document.createEvent()

const event = document.createEvent(type);

new Event

event = new Event(type, eventInit);

触发事件

可使用 new Event 通信,处理流程,达到解耦

开始吧

new CustomEvent
event = new Event(type, eventInit);

相比之前方式,它可以携带更多的参数了:

开始吧

兼容垫片(如果浏览器不支持 CustomEvent 的话):
(function () {
if (typeof CustomEvent !== “function”) {
var CustomEvent = function (event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };

  var evt = document.createEvent("CustomEvent");evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);return evt;
};CustomEvent.prototype = window.Event.prototype;window.CustomEvent = CustomEvent;

}
})();

这篇就写完了,大家如果觉得好的话可以多多点赞,赠人玫瑰,手有余香。我会继续努力奉献更高质量的文章的。

三行代码实现发布订阅,让面试官虎躯微微一震相关推荐

  1. 【EventBus】发布-订阅模式 ( 使用代码实现发布-订阅模式 )

    文章目录 一.发布-订阅模式 二.代码实现发布-订阅模式 1.订阅者接口 2.订阅者实现类 3.发布者 4.调度中心 5.客户端 一.发布-订阅模式 发布订阅模式 : 发布者 Publisher : ...

  2. 阿里发布内部(面试官)题库:2022年Java社招岗(正式版)面试题

    阿里巴巴2022年Java架构师岗面试题(正式版) 这不马上就是金三银四的面试跳槽季了嘛,马士兵老师也是通过一些小手段为大家拿到了一份阿里巴巴2022年Java架构师岗面试题(正式版)现在分享给大家, ...

  3. class没有发布到tomcat_面试官扎心一问:Tomcat 在 SpringBoot 中是如何启动的?

    作者:木木匠 my.oschina.net/luozhou/blog/3088908 前言 我们知道 SpringBoot 给我们带来了一个全新的开发体验,我们可以直接把 web 程序达成 jar 包 ...

  4. 面试官问我,使用Dubbo有没有遇到一些坑?我笑了。

    作者:肥朝 来自:feichao_java 前言 17年的时候,因为一时冲动没把持住(当然最近也有粉丝叫我再冲动一把再更新一波),结合面试题写了一个系列的Dubbo源码解析.目前公众号大部分粉丝都是之 ...

  5. atoi函数_吊打面试官 | 腾讯经典考点写代码实现atoi函数

    点击蓝字关注我哦 以下是本期干货视频视频后还附有文字版本哦 ▼<腾讯经典考点-写代码实现atoi函数>▼ ps:请在WiFi环境下打开,如果有钱任性请随意 在腾讯面试时,经常会被问到如何用 ...

  6. 面试官:来写个代码求一下两个数的最大公约数吧

    最近去面试了,面了几家公司,深刻认识到一个道理,越是基础的问题越重要,越能考察一个人的技术功底与逻辑思维.比如我们接下来要说的求两个数的最大公约数的问题.这类简单的算法题目一般会出现在面试环节,面试官 ...

  7. Vue响应式原理探究之“发布-订阅”模式

    前言 在面试题中经常会出现与"发布订阅"模式相关的题目,比如考察我们对Vue响应式的理解,也会有题目直接考验我们对"发布订阅"模式或者观察者模式的理解,甚至还会 ...

  8. 一个synchronized跟面试官扯了半个小时

    前言 话说上回HashMap跟面试官扯了半个小时之后,二面迎来了没有削弱前的钟馗,法师的钩子让安琪拉有点绝望.钟馗穿着有些微微泛黄的格子道袍,站在安琪拉对面,开始发难,其中让安琪拉印象非常深刻的是法师 ...

  9. 【EventBus】发布-订阅模式 ( Android 中使用 发布-订阅模式 进行通信 )

    文章目录 一.拷贝 发布-订阅模式 相关类 二.完整代码示例 一.拷贝 发布-订阅模式 相关类 将上一篇博客 [EventBus]发布-订阅模式 ( 使用代码实现发布-订阅模式 ) 写的 发布-订阅模 ...

最新文章

  1. 服务器ping你可以ping通,你ping服务器ping不同的解决方案!!
  2. java 万年历_非常实用的java万年历制作方法
  3. 线性链条件随机场与HMM在viterbi算法中的图解对比
  4. docker安装ubuntu镜像
  5. Linux网络编程——I/O复用之select详解
  6. 数据链路层中的LLC
  7. (转)AS3 面相对象 高级话题
  8. python爬虫re_python网络爬虫之三re正则表达式模块
  9. 用python实现websocket请求遇到的问题及解决方法。
  10. 对C#中事件的简单理解
  11. php抓包腾讯大王卡token,【大王卡专用抓包教程,内附视频链接】动态抓包
  12. matlab光伏最大功率,光伏系统最大功率点跟踪技术的比较
  13. 沈阳移动打造“爱贝通”、“校讯通”业务助少年儿童健康成长
  14. VMware虚拟机操作汇总
  15. ConcurrentHashMap插入与遍历时出现混乱
  16. 发明计算机的人的名人名言,16句关于科学家的名言
  17. 支付机构备付金管理过程
  18. 爬取某位大佬简书上所有文章并保存为pdf
  19. HGMF: Heterogeneous Graph-based Fusion for Multimodal Data with Incompleteness【多模态 异质图 不完整数据学习】
  20. DIB迪博数据库(2000-2018年)

热门文章

  1. 自制香浓芝麻酱的做法,重庆顶香味的老师傅手艺
  2. 多种PS技术,会让你的照片美的不行!!!
  3. 明明android已经设置好了调试模式,但是华为手机就是不能真机调试,那么可能是你手机模式没有调好
  4. 苹果a13_苹果A13性爆表!让安卓芯片全体“崩溃”!
  5. 为pdf批量建立书签目录
  6. css边框实现高度,CSS上的边框高度
  7. 腾讯地图引用到react项目
  8. 外贸三个月不出单就没工资,手里都是长线客户,是离职还是熬
  9. Android8+厨房,【教程】用安卓厨房制作你自己的卡刷包!你也可以是Romer !
  10. ios滑动区域卡顿和左右滑动,上下留白问题