日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

JavaScript中发布/订阅模式的理解

發(fā)布時(shí)間:2023/12/20 javascript 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript中发布/订阅模式的理解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

訂閱發(fā)布模式的介紹

發(fā)布訂閱模式,它定義了一種一對(duì)多的關(guān)系,可以使多個(gè)觀察者對(duì)象對(duì)一個(gè)主題對(duì)象進(jìn)行監(jiān)聽(tīng),當(dāng)這個(gè)主題對(duì)象發(fā)生改變時(shí),依賴的所有對(duì)象都會(huì)被通知到。

在生活中我們常常遇到這樣一種情況,我們?cè)谑褂眯侣凙PP看新聞的時(shí)候,每個(gè)人喜歡的新聞?lì)愋透鞑灰粯?#xff0c;比如我喜歡NBA,但是我們總不可能一天24小時(shí)在手機(jī)上一遍又一遍的刷新,我們就會(huì)去新聞?lì)l道中選擇NBA專欄來(lái)收藏,當(dāng)勇士或者湖人有最新消息,就會(huì)通知我們?nèi)ビ^看。

當(dāng)然從上面的場(chǎng)景中是一個(gè)典型的發(fā)布訂閱模式,APP的NBA專欄屬于發(fā)布者,像我一樣廣大愛(ài)好籃球的小伙伴夢(mèng)就屬于訂閱者,當(dāng)一有最新的消息,它們就會(huì)發(fā)布給我們。

實(shí)際用途

1.在jquery中很多地方都有發(fā)布訂閱的蹤跡,例如事件中on和trigger中封裝的方法。

2.尤大大的Vue,中子父組件通信使用的emit()和on()方法,使得組件得到解耦,開(kāi)發(fā)更加高效。

如何實(shí)現(xiàn)訂閱發(fā)布模式

1、首先想好誰(shuí)是發(fā)布者(比如上邊的APP的NBA專欄就是發(fā)布者);

2、然后給發(fā)布者添加一個(gè)緩存列表,用于存放回調(diào)函數(shù)來(lái)通知訂閱者(比如上面的我們球迷愛(ài)好者收藏了NBA專欄,相當(dāng)于向發(fā)布者注入了通知我們的函數(shù));

3、最后就是發(fā)布消息,發(fā)布者遍歷這個(gè)緩存列表,依次觸發(fā)訂閱的函數(shù)。

表捉急,端起小板凳,先看一下這個(gè)簡(jiǎn)單的發(fā)布訂閱模式:

let NBAcol={};//自定義一個(gè)NBA專欄對(duì)象 NBAcol.list=[];// 這里放一個(gè)列表用來(lái)緩存訂閱者的回調(diào)函數(shù) NBAcol.on=function(fun){this.list.push(fun); //把fn先存到列表中 }; //發(fā)布事件 NBAcol.emit=function(){this.list.forEach(cb => {cb.apply(this, arguments);});// 當(dāng)發(fā)布的時(shí)候再把列表里存的函數(shù)依次執(zhí)行 }; //小明的訂閱NBA專欄 NBAcol.on(function(team){console.log("我訂閱的球隊(duì)是:"+team) }) //小李的訂閱NBA專欄 NBAcol.on(function(team){console.log("我訂閱的球隊(duì)是:"+team) }) NBAcol.emit('湖人'); NBAcol.emit('勇士'); /* 我訂閱的球隊(duì)是:湖人; 我訂閱的球隊(duì)是:湖人; 我訂閱的球隊(duì)是:勇士; 我訂閱的球隊(duì)是:勇士; */ 復(fù)制代碼

上面就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的訂閱發(fā)布模式,不過(guò)從打印結(jié)果來(lái)看,有些尷尬,因?yàn)槠鋵?shí),小明只想訂閱湖人,小李要訂閱勇士。可是專欄都給他們推送了,顯然不太合理。之所以出現(xiàn)這種情況是因?yàn)樵趫?zhí)行on方法的時(shí)候?qū)⒂嗛喓瘮?shù)列表中的函數(shù)依次都執(zhí)行了。所以我們要對(duì)代碼進(jìn)行改造,我們可以先增加一個(gè)key,使訂閱者只訂閱自己感興趣的消息。

let NBAcol={};//自定義一個(gè)NBA專欄對(duì)象 NBAcol.list={};// 這里放一個(gè)列表用來(lái)緩存訂閱者的回調(diào)函數(shù) NBAcol.on=function(key,fun){// 如果還沒(méi)有訂閱過(guò)此類消息,給該類消息創(chuàng)建一個(gè)緩存列表if(!this.list[key]){this.list[key]=[];}this.list[key].push(fun); //把fn先存到列表中 }; //發(fā)布事件 NBAcol.emit=function(){let key=Array.prototype.shift.call(arguments);// 取出消息類型名稱let funs=this.list[key];//匹配對(duì)應(yīng)的回調(diào)函數(shù)的結(jié)合if(!funs||funs.length===0){//如果沒(méi)有訂閱過(guò)消息,則return;return;};funs.forEach(fun => {fun.apply(this, arguments);});// 當(dāng)發(fā)布的時(shí)候再把列表里存的函數(shù)依次執(zhí)行 }; //小明的訂閱NBA專欄 NBAcol.on('xiaomin',function(team){console.log("我訂閱的球隊(duì)是:"+team) }) //小李的訂閱NBA專欄 NBAcol.on('xiaoli',function(team){console.log("我訂閱的球隊(duì)是:"+team) }) NBAcol.emit('xiaomin','湖人'); NBAcol.emit('xiaoli','勇士'); /* 我訂閱的球隊(duì)是:湖人; 我訂閱的球隊(duì)是:勇士; */ 復(fù)制代碼

這樣子就可以啦,這個(gè)訂閱發(fā)布的核心功能已經(jīng)體現(xiàn)了。

如何取消事件的訂閱

比如上面的列子,假如我們訂閱了很多東西,不喜歡的時(shí)候我們要取消訂閱,該怎么辦呢?看如下代碼:

NBAcol.remove=function(key, fun) {// 這回我們加入了取消訂閱的方法let funs = this.list[key];// 如果緩存列表中沒(méi)有函數(shù),返回falseif (!funs) return false;// 如果沒(méi)有傳對(duì)應(yīng)函數(shù)的話// 就會(huì)將key值對(duì)應(yīng)緩存列表中的函數(shù)都清空掉if (!fun) {funs && (funs.length = 0);} else {// 遍歷緩存列表,看看傳入的fun與哪個(gè)函數(shù)相同// 如果相同就直接從緩存列表中刪掉即可funs.forEach((cb, i) => {if (cb === fun) {funs.splice(i, 1);}});}}// 取消dog方法的訂閱NBAcol.remove('xiaoli',function(team){console.log("我訂閱的球隊(duì)是:"+team)}); 復(fù)制代碼

這樣就可以取消訂閱啦,但是實(shí)際的開(kāi)源代碼中,封裝遠(yuǎn)比這要復(fù)雜,比如要考慮訂閱數(shù)量,還有多模塊訂閱的封裝等等,所以在這里我們還得在實(shí)際的業(yè)務(wù)模塊中詳細(xì)考慮。

發(fā)布訂閱模式的缺點(diǎn):

當(dāng)然一個(gè)任何一個(gè)東西都是有兩面性的,同樣發(fā)布訂閱模式存在以下問(wèn)題:

1、創(chuàng)建訂閱者需要消耗一定的時(shí)間和內(nèi)存。

2、雖然可以弱化對(duì)象之間的聯(lián)系,如果過(guò)度使用的話,反而使代碼不好理解及代碼不好維護(hù)等等。

轉(zhuǎn)載于:https://juejin.im/post/5b2e65fee51d4558df370532

總結(jié)

以上是生活随笔為你收集整理的JavaScript中发布/订阅模式的理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。