javascript 發(fā)布-訂閱模式 實(shí)例詳解
一、核心概述
發(fā)布訂閱模式主要包含三大塊:緩存數(shù)組、訂閱、發(fā)布
緩存數(shù)組 | 一個數(shù)組[] |
訂閱 | 往數(shù)組里面壓入函數(shù)fn |
發(fā)布 | 里面循環(huán)遍歷數(shù)組,然后執(zhí)行數(shù)組中的函數(shù)。 |
二、簡單代碼實(shí)現(xiàn)及改進(jìn)
(1)實(shí)現(xiàn)
var subpub = {}; subpub.cache = []; subpub.subscribe = function(fn){ this.cache.push(fn) } subpub.publish = function(){ for(var i in this.cache){ this.cache[i].apply(this,arguments) } } //test subpub.subscribe(function(price,square){ console.log("price:"+price) console.log(square) }) subpub.publish(200,102); subpub.publish(300,153)
(2)改進(jìn) --- 主要針對訂閱者不需要接收到所有的發(fā)布事件---key
var subpub = {}; subpub.cache = {}; //是一個數(shù)組對象 subpub.subscribe = function (key, fn) { if (!this.cache[key]) { //訂閱的事情在緩存里面沒有,則添加到緩存 this.cache[key] = []; } this.cache[key].push(fn); } subpub.publish = function () { //傳入?yún)?shù)的第一個是指訂閱的類型 var key = Array.prototype.splice.apply(arguments,[0,1]); for (var i in this.cache[key]) { this.cache[key][i].apply(this, arguments) } } //test subpub.subscribe('lowPrice',function (price, square) { //A訂閱價格低于300的 console.log("price:" + price) console.log(square) }) subpub.subscribe('highPrice',function (price, square) { //B訂閱價格高于300的 console.log("price:" + price) console.log(square) }) subpub.publish('lowPrice',200, 102); subpub.publish('highPrice',400, 153)
取消訂閱的事件
subpub.subscribe('lowPrice', fn1 = function (price, square) { //A訂閱價格低于300的 console.log(square) }) subpub.subscribe('lowPrice', fn11 = function (price, square) { //A訂閱價格低于300的 console.log("price1:" + price) console.log(square) }) subpub.subscribe('highPrice', fn2 = function (price, square) { //B訂閱價格高于300的 console.log("price:" + price) console.log(square) }) //取消訂閱的事件 subpub.remove = function (key, fn) { if (!this.cache[key]) { //如果key對應(yīng)的消息沒有被訂閱,則直接返回 return false } if(!fn){ //如果沒有傳入fn,則移除key對應(yīng)的所有消息 this.cache[key] && (this.cache[key].length=0) } else { this.cache[key] = this.cache[key].filter(function (cur, index) { return cur !== fn }) } } subpub.remove('lowPrice',fn1) subpub.publish('lowPrice', 200, 102);
取消的時候,注意區(qū)分不同情況。上述使用了filter函數(shù)用來過濾需要取消訂閱的事件
三、現(xiàn)實(shí)項(xiàng)目需求
網(wǎng)站登錄====》登錄以后需要在各處顯示客戶的信息。不能在用戶登陸后去依次調(diào)用模塊的刷新或或其他相關(guān)函數(shù),要監(jiān)聽登錄這一次操作。
//封裝一下 var event = { cache: {}, subscribe: function (key, fn) { if (!this.cache[key]) { //訂閱的事情在緩存里面沒有,則添加到緩存 this.cache[key] = []; } this.cache[key].push(fn); }, publish: function () { //傳入?yún)?shù)的第一個是指訂閱的類型 var key = Array.prototype.splice.apply(arguments, [0, 1]); for (var i in this.cache[key]) { this.cache[key][i].apply(this, arguments) } }, remove: function (key, fn) { if (!this.cache[key]) { //如果key對應(yīng)的消息沒有被訂閱,則直接返回 return false } if (!fn) { //如果沒有傳入fn,則移除key對應(yīng)的所有消息 this.cache[key] && (this.cache[key].length = 0) } else { this.cache[key] = this.cache[key].filter(function (cur, index) { return cur !== fn }) } } }; var eventForPub = function (obj) { for (var i in event) { obj[i] = event[i] } } var login = {}; eventForPub(login) var headItem = (function () { login.subscribe('login', function (data) { headItem.setAvatar(data.avatar) }) return { setAvatar: function (data) { console.log("頭部顯示客戶信息") } } })(); var buyItem = (function () { login.subscribe('login', function (data) { buyItem.setAvatar(data.avatar) }) return { setAvatar: function (data) { console.log("購物車顯示客戶信息") } } })(); var data={avatar:'qqqq'} login.publish('login',data);
運(yùn)行結(jié)果如下:
更多設(shè)計模式相關(guān)知識點(diǎn),還可以參考本站文章:
http://www.dbjr.com.cn/article/252965.htm
http://www.dbjr.com.cn/article/27973.htm
- JavaScript事件發(fā)布/訂閱模式原理與用法分析
- JavaScript實(shí)現(xiàn)與使用發(fā)布/訂閱模式詳解
- JavaScript中發(fā)布/訂閱模式的簡單實(shí)例
- JS前端設(shè)計模式之發(fā)布訂閱模式詳解
- js 發(fā)布訂閱模式的實(shí)例講解
- JavaScript設(shè)計模式之觀察者模式(發(fā)布訂閱模式)原理與實(shí)現(xiàn)方法示例
- JavaScript設(shè)計模式之觀察者模式與發(fā)布訂閱模式詳解
- 詳解JavaScript設(shè)計模式中的享元模式
- JavaScript設(shè)計模式之單例模式應(yīng)用場景案例詳解
- JavaScript 設(shè)計模式 安全沙箱模式
- JavaScript設(shè)計模式之觀察者模式(發(fā)布者-訂閱者模式)
相關(guān)文章
JavaScript自定義Webpack配置實(shí)現(xiàn)流程介紹
本系列主要整理前端面試中需要掌握的知識點(diǎn)。本節(jié)介紹webpack如何優(yōu)化前端性能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-10-10用JS實(shí)現(xiàn)HTML標(biāo)簽替換效果
用JS實(shí)現(xiàn)HTML標(biāo)簽替換效果...2007-06-06JavaScript轉(zhuǎn)換農(nóng)歷類實(shí)現(xiàn)及調(diào)用方法
農(nóng)歷是日常生活中不可或缺的一部分,它與人類的生活息息相關(guān),從某種程度上說,它一直伴隨著我們,今天的任務(wù)是JavaScript轉(zhuǎn)換農(nóng)歷類的實(shí)現(xiàn),感興趣的你可以千萬不要錯過,希望本文對你有所幫助2013-01-01