【SSD系列】傻傻的,3行代码一个订阅发布中心,不会不知道吧

简介: 无处不在的订阅发布模式,也是常备手写系列,可见其地位。其实,在浏览器端,3行代码,没错3行代码,你就可以拥有一个具备订阅,取消订阅,发布,并具备once能力的订阅发布中心。

1.JPG


关于[SSD系列]


专门为8月征文活动而建立的系列,收集整理前端一些有意思或者我们不重视的内容,可能是部分掘友不知道的。


前言


无处不在的订阅发布模式,也是常备手写系列,可见其地位。


其实,在浏览器端,3行代码,没错3行代码,你就可以拥有一个具备订阅,取消订阅,发布,并具备once能力的订阅发布中心。


4行代码的订阅发布中心


订阅发布中心代码


window._on = window.addEventListener;
window._off = window.removeEventListener;
window._emit = (type, data) => window.dispatchEvent(new CustomEvent(type, { detail: data }));;
window._once = (type, callback) => window.addEventListener(type, callback, { once: true, capture: true });
复制代码


标题是3行也是可以的,把1,2行合并一下:


(window._on = window.addEventListener, window._off = window.removeEventListener);
复制代码


测试代码


function onEventX(ev) {
    console.log("event-x 收到数据:", ev.detail);
}
// 订阅
window._on("event-x", onEventX);
window._once("event-once", ev => console.log("event-once 收到数据:", ev.detail));
// once
window._emit("event-once", { uid: -100, message: "you love me" });
window._emit("event-once", { uid: -100, message: "you love me" });
// 订阅和取消订阅
window._emit("event-x", { uid: 100, message: "i love you" })
window._off("event-x", onEventX);
window._emit("event-x", { uid: 100, message: "i love you" })
复制代码


输出结果




1.JPG


是不是有点小惊喜。


原理浅析



window是表象,根源是 EventTarget


其一共三个方法,也正是这三个方法,让其自身是一个订阅发布中心:



Window的继承关系:


2.JPG


Document的继承关系:


3.JPG


Element的继承关系:


4.JPG


所以document和window对象均是一个订阅发布中心。

更重要的是我们常用的div, span, input等等nodeType为1的元素节点,也统统是一个订阅发布中心。


假如你连nodeType也不清楚,没关系,请参见Node.nodeType


当前版本的问题


  1. 不能多实例化啊
  2. 挂载window上太丑了
  3. 不能多参数啊
    答:要那么多参数干嘛
  4. 参数从ev.detail上获取
    答:还好
  5. 不能在node, web worker中使用啊
    答:node要你写吗, 自带啊。 web worker嘛,确实。
  6. ........


到这里,我不生气,真的不生气, 特定场景解决特定问题就完毕了。 1毛钱还想上天啊。


但是就算是1毛钱,我也希望大家获得更好的体验,所以要改造升级。


3以及之后的别想了,我们把1,2点进行完美升级。


升级



升级后的代码会多一点,2倍吧,一共6行代码


代码


class EventEmitter extends EventTarget {
    on = this.addEventListener;
    off = this.removeEventListener;
    emit = (type, data) => this.dispatchEvent(new CustomEvent(type, { detail: data }));
    once = (type, callback) => this.on(type, callback, { once: true, capture: true });
}
复制代码


测试代码


var emitter = new EventEmitter();
        function onEventX(ev) {
            console.log("event-x 收到数据:", ev.detail);
        }
        // 订阅
        emitter.on("event-x", onEventX);
        emitter.once("event-once", ev => console.log("event-once 收到数据:", ev.detail));
        // 发布
        emitter.emit("event-once", { uid: -100, message: "you love me" });
        emitter.emit("event-once", { uid: -100, message: "you love me" });
        emitter.emit("event-x", { uid: 100, message: "i love you" })
        emitter.off("event-x", onEventX);
        emitter.emit("event-x", { uid: 100, message: "i love you" })
复制代码


完美,名字好看了,使用方便了,也支持多实例了。


结果


5.JPG


总结



是不是很简单,其实不用第三方库,你也可以拥有订阅发布中心,就这么简单。

要是都看到这了,都不点个赞,那就是你的不对了。

相关文章
|
4月前
|
消息中间件 安全 物联网
MQTT常见问题之新增自定义主题后平台侧收不到发布的数据如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
1月前
|
Cloud Native Java Serverless
一键上天!如何将Spring PetClinic瞬间迁移到云端函数计算平台
【8月更文挑战第8天】在现代云原生开发中,将Spring应用迁移到Serverless环境正成为趋势。本文通过对比传统部署与函数计算,指导如何快速部署Spring PetClinic应用。传统部署需手动配置服务器和中间件,而函数计算则免除了这些步骤,仅需上传代码。首先,准备好Spring PetClinic源码或jar包;接着选择函数计算平台,本文以阿里云为例;随后对应用进行适配,并使用Maven构建部署包;登录阿里云控制台上传jar包并配置HTTP触发器;最后测试应用确保正常运行。
34 3
|
18天前
|
消息中间件 缓存 Kafka
【Azure 事件中心】使用Kafka消费Azure EventHub中数据,遇见消费慢的情况可以如何来调节呢?
【Azure 事件中心】使用Kafka消费Azure EventHub中数据,遇见消费慢的情况可以如何来调节呢?
|
20天前
|
Kubernetes 监控 测试技术
在K8S中,如何实现上线发布流程(灰度发布)?
在K8S中,如何实现上线发布流程(灰度发布)?
|
4月前
|
运维 监控 Cloud Native
应用研发平台EMAS常见问题之尝试设置小米的通道但是小米手机收不到消息如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
|
4月前
|
移动开发 运维 监控
应用研发平台EMAS产品常见问题之rn的插件收不到通知消息如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
|
消息中间件 物联网
EMQ支不支持延迟消息, 如何实现
EMQ 是一个基于 Erlang/OTP 架构的开源物联网消息中间件(MQTT Broker)。目前的 EMQ 版本(截至 2023 年 7 月)不直接支持延迟消息。然而,你可以通过以下方法实现延迟消息的功能:
108 0
|
4月前
|
移动开发 小程序 Go
【社区每周】小程序消息订阅插件升级为消息订阅接口(2022年8月第五期)
【社区每周】小程序消息订阅插件升级为消息订阅接口(2022年8月第五期)
32 0
|
9月前
|
SQL 消息中间件 Java
想要流畅体验 TDengine 3.0 数据订阅功能?要点都在这里
在本文中,TDengine 资深研发将以 TDengine 3.0 为对象,为大家介绍数据订阅功能的正确打开方式,给到有需要的人作参考指南,避免走入应用误区。
188 0
【鸿蒙】订阅分布式数据变化
客户端需要实现KvStoreObserver接口。 构造并注册KvStoreObserver实例。
【鸿蒙】订阅分布式数据变化