2020-03-20 發(fā)布-訂閱模式 EventEmitter

發(fā)布-訂閱模式饲帅,又稱觀察者模式矛绘。
一對(duì)多:當(dāng)一個(gè)對(duì)象更新時(shí)虑鼎,所有依賴它的對(duì)象都將得到通知并自動(dòng)更新辱匿。
關(guān)鍵代碼:在抽象類(lèi)里有一個(gè) array list 來(lái)存放觀察者們。
關(guān)鍵概念:即使沒(méi)有觀察者炫彩,主體也可以獨(dú)自存在并正常運(yùn)行匾七。

主體“發(fā)布”事件。
觀察者通過(guò)“訂閱”事件來(lái)觀察對(duì)象江兢。

優(yōu)點(diǎn):
有助于解耦昨忆,保持功能的隔絕。
因?yàn)橛|發(fā)事件的代碼和監(jiān)聽(tīng)事件的代碼是完全分離的划址。

缺點(diǎn):

  1. 如果觀察者和主體之間有循環(huán)依賴扔嵌,系統(tǒng)會(huì)循環(huán)崩潰。
  2. 主體有很多直接/間接觀察者的話夺颤,通知到所有觀察者很花時(shí)間痢缎。
  3. 觀察者們不知道主體怎么發(fā)生變化,只知道它變了世澜。

代碼1 - 紅寶書(shū)版:

function EventTarget() {
  this.handler = {}
}
EventTarget.prototype = {
  constructor: EventTarget,
  addHander(type, handler) {
    //增加事件
    if (typeof this.handler[type] == 'undefined') {
      this.handler[type] = []
    }
    this.handler[type].push(handler) //可能有很多方法独旷,把方法做為數(shù)組
  },
  fire(event) {
    //觸發(fā)事件,傳入觸發(fā)的事件名和參數(shù)
    if (!event.target) {
      //如果沒(méi)有傳入事件對(duì)象寥裂,把實(shí)例做為對(duì)象
      event.target = this
    }
    //事件方法做為數(shù)組存在
    const handlers = this.handler[event.type]
    //if (handlers instanceof Array) {
    if (Array.isArray(handlers)) {
      const length = handlers.length
      for (let k = 0; k < length; k++) {
        handlers[k](event)
      }
    }
  },
  removeHander(type, handler) {
    //刪除事件
    const handlers = this.handler[type]
    //if (handlers instanceof Array) {
    if (Array.isArray(handlers)) {
      const length = handlers.length
      for (let k = 0; k < length; k++) {
        if (handlers[k] == handler) {
          this.handler[type].splice(k, 1)
          break
        }
      }
    }
  }
}
let event = new EventTarget()
function hello() {
  console.log('hi')
}
event.addHander('click', hello)
event.fire({
  type: 'click'
})

代碼2 - es6版:

// to do

調(diào)用代碼:

        function handleMessage(event){
            alert("Message received: " + event.message);
        }

        var target = new EventTarget();
        
        target.addHandler("message", handleMessage);

        target.fire({ type: "message", message: "Hello world!"});
        
        target.removeHandler("message", handleMessage);

        target.fire({ type: "message", message: "Hello world!"});

結(jié)合“寄生組合式繼承”(紅寶書(shū)p172):

        function Person(name, age){
            EventTarget.call(this);
            this.name = name;
            this.age = age;
        }
        
        inheritPrototype(Person,EventTarget);
        
        Person.prototype.say = function(message){
            this.fire({type: "message", message: message});
        };
        
        
        
        function handleMessage(event){
            alert(event.target.name + " says: " + event.message);
        }

        var person = new Person("Nicholas", 29);
        
        person.addHandler("message", handleMessage);
        
        person.say("Hi there.");
        function object(o){
            function F(){}
            F.prototype = o;
            return new F();
        }
            
        function inheritPrototype(subType, superType){
            var prototype = object(superType.prototype);   //create object
            prototype.constructor = subType;               //augment object
            subType.prototype = prototype;                 //assign object
        }

參考資料:

  1. 《紅寶書(shū)》第22章 高級(jí)技巧 - 自定義事件 p616 - 618
  2. 菜鳥(niǎo)教程 https://www.runoob.com/design-pattern/observer-pattern.html
  3. 霧切's blog 自定義事件/觀察者模式
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嵌洼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子封恰,更是在濱河造成了極大的恐慌麻养,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诺舔,死亡現(xiàn)場(chǎng)離奇詭異鳖昌,居然都是意外死亡备畦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)许昨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)懂盐,“玉大人,你說(shuō)我怎么就攤上這事糕档±蚰眨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵速那,是天一觀的道長(zhǎng)俐银。 經(jīng)常有香客問(wèn)我,道長(zhǎng)琅坡,這世上最難降的妖魔是什么悉患? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮榆俺,結(jié)果婚禮上售躁,老公的妹妹穿的比我還像新娘。我一直安慰自己茴晋,他們只是感情好陪捷,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著诺擅,像睡著了一般市袖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上烁涌,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天苍碟,我揣著相機(jī)與錄音,去河邊找鬼撮执。 笑死微峰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抒钱。 我是一名探鬼主播蜓肆,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谋币!你這毒婦竟也來(lái)了仗扬?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蕾额,失蹤者是張志新(化名)和其女友劉穎早芭,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體诅蝶,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡退个,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年精肃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帜乞。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖筐眷,靈堂內(nèi)的尸體忽然破棺而出黎烈,到底是詐尸還是另有隱情,我是刑警寧澤匀谣,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布照棋,位于F島的核電站,受9級(jí)特大地震影響武翎,放射性物質(zhì)發(fā)生泄漏烈炭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一宝恶、第九天 我趴在偏房一處隱蔽的房頂上張望符隙。 院中可真熱鬧,春花似錦垫毙、人聲如沸霹疫。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丽蝎。三九已至,卻和暖如春膀藐,著一層夾襖步出監(jiān)牢的瞬間屠阻,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工额各, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留国觉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓臊泰,卻偏偏與公主長(zhǎng)得像蛉加,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缸逃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容