成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

事件訂閱的幾種實現風格

開發 前端
三種風格,第一種是監聽器本身作為標識,第二種是使用額外的一個 id(數字或字符串)來代表監聽器,第三種是在調用監聽方法時,直接返回一個可以取消監聽的函數。

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

事件訂閱是模塊間解耦的常見方式。

比如相隔遙遠的兩個組件,可以通過一個訂閱,一個發布的方式,實現數據通信。

下面我們來看看事件訂閱的幾種設計風格。

監聽器函數

第一種是 使用監聽器函數本身作為標識符。

常見的場景有 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(數字或字符串)來代表監聽器,第三種是在調用監聽方法時,直接返回一個可以取消監聽的函數。

責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2024-05-14 08:03:51

C#EventArgs?屬性

2023-08-14 14:04:14

JavaScript函數式編程

2025-04-17 07:10:03

API架構項目

2009-12-23 16:06:46

WPF事件策略

2021-08-16 07:26:42

服務訂閱機制

2024-02-29 08:21:05

MediatR.NET庫傳遞消息

2009-07-29 17:44:02

ibmdwJava

2023-02-08 08:43:55

前端繼承原型

2021-10-07 20:36:45

Redis集群場景

2025-02-25 09:29:34

2024-05-10 07:44:23

C#進程程序

2009-09-18 12:29:55

2010-08-05 09:39:17

Flex頁面跳轉

2022-12-02 07:28:58

Event訂閱模式Spring

2023-02-07 07:25:36

Spring事件驅動

2010-04-30 16:22:07

Unix終端

2022-05-19 14:14:26

go語言限流算法

2009-12-02 20:02:18

PHP實現頁面跳轉

2020-05-08 11:13:28

Python數據技術

2023-05-07 07:56:53

Python方式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一级欧美三级在线观看 | 欧美激情a∨在线视频播放 成人免费共享视频 | 午夜一级黄色片 | 国产在线中文字幕 | 久久国产婷婷国产香蕉 | 国产99视频精品免费视频7 | 狠狠色网 | 国产激情视频在线免费观看 | 久久亚洲一区二区 | 一区二区三区四区在线播放 | 亚洲欧美日韩精品久久亚洲区 | 操射视频| 午夜视频在线观看视频 | 黄页网址在线观看 | a亚洲精品 | 亚洲在线日韩 | 一级毛片免费完整视频 | 中文字幕在线一区 | 97国产在线观看 | 99爱在线视频 | 亚洲美女视频 | 久久精品二区 | 99re视频在线免费观看 | 欧美精品一区三区 | 欧美一区二区免费视频 | 中文字幕一区二区三区在线观看 | 久久久久久av | 日韩欧美一区二区三区免费观看 | 欧美久久电影 | 最新中文在线视频 | 一区二区视频 | 羞羞的视频免费看 | 涩涩视频在线播放 | 日本一区二区电影 | 四季久久免费一区二区三区四区 | 国产精品成人一区二区三区夜夜夜 | 国产精品福利在线观看 | 精品香蕉一区二区三区 | 欧美成人精品 | 91精品久久久久久久久 | 国产精品大片在线观看 |