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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单的写一个发布订阅器

發布時間:2024/9/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单的写一个发布订阅器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

發布-訂閱模式在開發中的應用其實是很廣泛的,比如大家都知道的 Vue,使用數據驅動模板的改變,將我們的雙手從繁瑣的 dom 操作中解放出來,稍微懂一些原理的同學們都知道,其雙向數據綁定就是通過數據劫持、發布-訂閱和 dom 模板編譯實現的,就算不了解這個的同學,js 中的事件監聽相信做前端開發的同學都寫過;

其實事件監聽就是一個訂閱的操作,當某個事件觸發的時候,對該事件監聽時傳入的 callback 就會被執行,這就是一個完整的發布的-訂閱流程;接下來我們就來簡單的寫一下一個發布訂閱器:

思路:

俗話說:磨刀不誤砍柴工,在動手之前,縷清一下思路是有必要的,首先我們要明確這個發布訂閱器的功能,其中包括

基本功能:

  • 可添加訂閱者
  • 可觸發消息通知某個訂閱器執行其中的所有訂閱者
  • 可刪除指定訂閱者

升級功能:

  • 可同時給多個訂閱器添加訂閱者
  • 可刪除指定訂閱器中的所有訂閱者
  • 可指定同時刪除多個訂閱器或者直接清空所有訂閱器
  • 可添加一次性訂閱(該訂閱者一旦被執行,就會在訂閱器中移除)
  • 處理好 this 指向和實現鏈式調用
  • 添加錯誤判斷和提醒機制

接下來我們就分兩版上代碼:

基礎版

/*** 發布訂閱器構造函數*/ var Publisher = (function() {function Publisher() {this._subs = {}; // 維護一個訂閱器列表}/*** 添加訂閱者* 若訂閱者需要插入的訂閱器不存在,則新創建一個* @param { string } type - 需要添加訂閱者的訂閱器名* @param { function } func - 訂閱者*/Publisher.prototype.addSub = function(type, func) {if(!this._subs[type]) this._subs[type] = [];this._subs[type].push(func);};/*** 發布通知* 通知指定訂閱器執行其中的每個訂閱者* @param { string } type - 需要通知其發布消息的訂閱器名*/Publisher.prototype.notify = function(type) {if(!this._subs[type]) return;var args = Array.prototype.slice.call(arguments, 1);this._subs[type].forEach(function(item) {item.apply(this, args);}, this);};/*** 刪除訂閱者* @param { string } type - 指定操作的訂閱器名* @param { function } func - 指定需要刪除的訂閱者*/Publisher.prototype.destory = function(type, func) {this._subs[type].forEach(function(item, index, array) {(item === func) && array.splice(index, 1);}, this);};return Publisher; }()); 復制代碼

基礎版就如上面的代碼,以最簡單的方式實現一個發布訂閱器的基本功能(能訂閱,并能接收消息,還能指定刪除)

升級版:

/*** 發布訂閱器構造函數*/ var Publisher = (function() {function Publisher() {this._subs = {};}/*** 添加訂閱者* 若訂閱者需要插入的訂閱器不存在,則新創建一個* 若傳入的訂閱器名為一個數組,則遍歷數組內的每個訂閱器添加訂閱者* @param { string|Array<string> } type - 需要添加訂閱者的訂閱器名* @param { function } func - 訂閱者* @returns { object } - 發布器實例,可實現鏈式調用*/Publisher.prototype.addSub = function(type, func) {if(Array.isArray(type)) {type.forEach(function(item) {this.addSub(item, func);}, this);} else {(this._subs[type] || (this._subs[type] = [])).push(func);}return this;};/*** 添加單次訂閱* 當該訂閱者在被通知執行一次之后會從訂閱器中移除* @param { string|Array<string> } type - 需要添加訂閱者的訂閱器名* @param { function } func - 訂閱者* @returns { object } - 發布器實例,可實現鏈式調用*/Publisher.prototype.once = function(type, func) {function onceAdd() {var args = Array.prototype.slice(arguments);this.destory(type, onceAdd);func.apply(this, args);}this.addSub(type, onceAdd);return this;};/*** 發布通知* 通知指定訂閱器執行其中的每個訂閱者* @param { string } type - 需要通知其發布消息的訂閱器名* @returns { object } - 發布器實例,可實現鏈式調用*/Publisher.prototype.notify = function(type) {if(this._subs[type] === void 0) throw TypeError("Can't find the " + type + " event in the Publisher");var args = Array.prototype.slice.call(arguments, 1);this._subs[type].forEach(function(item) {item.apply(this, args);}, this);return this;};/*** 刪除訂閱器/訂閱者* 若沒有傳入參數直接調用方法,將清空整個訂閱器列表* 若只傳入了訂閱器類型參數,沒有指定刪除的訂閱者,則刪除該訂閱器* @param { string|Array<string> } type - 指定操作的訂閱器名,可用數組傳入多個需要操作的訂閱器名* @param { function } func - 指定需要刪除的訂閱者* @return { object } - 發布器實例,可實現鏈式調用*/Publisher.prototype.destory = function(type, func) {if(func && typeof func !== 'function') throw TypeError('The param "func" should be a function!');if(!arguments.length) {this._subs = {};return this;}if(Array.isArray(type)) {type.forEach(function(item) {this.destory(item, func);}, this);}if(!func) {delete this._subs[type];} else {this._subs[type].forEach(function(item, index, array) {(item === func) && array.splice(index, 1);}, this);}return this;};return Publisher; }()); 復制代碼

以上就是一個簡單的發布訂閱器了,若有什么不足的地方,還望各位同學指正!

轉載于:https://juejin.im/post/5b2602edf265da59aa2d879f

總結

以上是生活随笔為你收集整理的简单的写一个发布订阅器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。