日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
事件訂閱的幾種實(shí)現(xiàn)風(fēng)格

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

創(chuàng)新互聯(lián)是一家專(zhuān)業(yè)提供寶應(yīng)企業(yè)網(wǎng)站建設(shè),專(zhuān)注與成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、H5開(kāi)發(fā)、小程序制作等業(yè)務(wù)。10年已為寶應(yīng)眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專(zhuān)業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

事件訂閱是模塊間解耦的常見(jiàn)方式。

比如相隔遙遠(yuǎn)的兩個(gè)組件,可以通過(guò)一個(gè)訂閱,一個(gè)發(fā)布的方式,實(shí)現(xiàn)數(shù)據(jù)通信。

下面我們來(lái)看看事件訂閱的幾種設(shè)計(jì)風(fēng)格。

監(jiān)聽(tīng)器函數(shù)

第一種是 使用監(jiān)聽(tīng)器函數(shù)本身作為標(biāo)識(shí)符。

常見(jiàn)的場(chǎng)景有 DOM 事件的綁定:

const handler = () {
// do something
}

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

此外還有 Node.js 的 EventEmitter 類(lèi),很多支持監(jiān)聽(tīng)事件的類(lèi)都繼承了它。用法為:

import { EventEmitter } from "node:events";

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

myEmitter.on("event", handler); // 綁定事件
myEmitter.emit("event"); // 打印了內(nèi)容

myEmitter.off("event", handler); // 取消事件
myEmitter.emit("event"); // 無(wú)事發(fā)生

原理很簡(jiǎn)單,就是維護(hù)一個(gè)映射表上,key 為事件名,value 為要順序執(zhí)行的監(jiān)聽(tīng)器,大概這樣:

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

一個(gè)監(jiān)聽(tīng)器函數(shù)就是一個(gè)唯一的對(duì)象,通過(guò)它可以找出在對(duì)應(yīng)事件下的位置,將其從列表中移除,就算是取消了事件綁定。

取消綁定邏輯大概為:

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

訂閱 id

通過(guò)一個(gè) id 來(lái)代表綁定的監(jiān)聽(tīng)器。

經(jīng)典場(chǎng)景為 setTimeout:

const timeoutId = setTimeout(() {
// ...
}, 1000); // 訂閱

clearTimeout(timeoutId); // 取消

實(shí)現(xiàn)原來(lái)基本類(lèi)似前一種方式,只是改為用 id 來(lái)作為標(biāo)識(shí)。

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

返回封裝好的取消綁定方法

上面兩種寫(xiě)法,都需要一個(gè)變量額外保存標(biāo)識(shí),然后再使用事件訂閱對(duì)象專(zhuān)門(mén)的取消訂閱函數(shù),難免有點(diǎn)繁瑣。

我們對(duì)第一種風(fēng)格,可以做一個(gè)封裝:

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

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

這種寫(xiě)法直接調(diào)用返回的函數(shù)即可解綁,不需要保存 id 和一個(gè)專(zhuān)門(mén)的取消訂閱函數(shù),代碼更簡(jiǎn)潔。

常見(jiàn)場(chǎng)景是 React 的 useEffect:

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

結(jié)尾

三種風(fēng)格,第一種是監(jiān)聽(tīng)器本身作為標(biāo)識(shí),第二種是使用額外的一個(gè) id(數(shù)字或字符串)來(lái)代表監(jiān)聽(tīng)器,第三種是在調(diào)用監(jiān)聽(tīng)方法時(shí),直接返回一個(gè)可以取消監(jiān)聽(tīng)的函數(shù)。


當(dāng)前題目:事件訂閱的幾種實(shí)現(xiàn)風(fēng)格
文章URL:http://m.5511xx.com/article/djsgecp.html