事件订阅的几种实现风格

大家好,我是前端西瓜哥。

创新互联是一家专业提供宝应企业网站建设,专注与成都做网站、网站设计、H5开发、小程序制作等业务。10年已为宝应众多企业、政府机构等服务。创新互联专业网站建设公司优惠进行中。

事件订阅是模块间解耦的常见方式。

比如相隔遥远的两个组件,可以通过一个订阅,一个发布的方式,实现数据通信。

下面我们来看看事件订阅的几种设计风格。

监听器函数

第一种是 使用监听器函数本身作为标识符。

常见的场景有 DOM 事件的绑定:

const handler = () {
// do something
}

window.addEventListener('resize', handler); // 绑定事件
window.removeEventListener('resize', handler); // 取消事件

此外还有 Node.js 的 EventEmitter 类,很多支持监听事件的类都继承了它。用法为:

import { EventEmitter } from "node:events";

const myEmitter = new EventEmitter();
const handler = () {
console.log("前端西瓜哥");
};

myEmitter.on("event", handler); // 绑定事件
myEmitter.emit("event"); // 打印了内容

myEmitter.off("event", handler); // 取消事件
myEmitter.emit("event"); // 无事发生

原理很简单,就是维护一个映射表上,key 为事件名,value 为要顺序执行的监听器,大概这样:

{
'resize': [handler1, handler2],
'click': [handler3, handler4]
}

一个监听器函数就是一个唯一的对象,通过它可以找出在对应事件下的位置,将其从列表中移除,就算是取消了事件绑定。

取消绑定逻辑大概为:

const index = map[eventName].indexOf(handler);
if (index !== -1) {
map[eventName].splice(index, 1);
}

订阅 id

通过一个 id 来代表绑定的监听器。

经典场景为 setTimeout:

const timeoutId = setTimeout(() {
// ...
}, 1000); // 订阅

clearTimeout(timeoutId); // 取消

实现原来基本类似前一种方式,只是改为用 id 来作为标识。

{
[eventName]: [
{id: 1, hander: handler1},
{id: 2, hander: handler2},
]
}

返回封装好的取消绑定方法

上面两种写法,都需要一个变量额外保存标识,然后再使用事件订阅对象专门的取消订阅函数,难免有点繁琐。

我们对第一种风格,可以做一个封装:

const bindEvent = (target, eventName, handler) => {
target.addEventListener('resize', handler); // 绑定
return () {
target.removeEventListener('resize', handler); // 取消
}
}

const unBindEvent = bindEvent(window, 'resize', handler); // 封装的绑定
unBindEvent(); // 封装的取消

这种写法直接调用返回的函数即可解绑,不需要保存 id 和一个专门的取消订阅函数,代码更简洁。

常见场景是 React 的 useEffect:

const App = () {
useEffect(() {
const handler = () {
// ...
}
window.addEventListener('resize', handler); // 绑定事件
return () {
window.removeEventListener('resize', handler); // 取消事件
}
}, [])
}

结尾

三种风格,第一种是监听器本身作为标识,第二种是使用额外的一个 id(数字或字符串)来代表监听器,第三种是在调用监听方法时,直接返回一个可以取消监听的函数。

网站栏目:事件订阅的几种实现风格
网页地址:http://www.36103.cn/qtweb/news4/21604.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联