亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

EventEmitter的實(shí)現(xiàn)

CoreDump / 2140人閱讀

摘要:實(shí)例方法的話,最核心的就是分別是添加事件,刪除事件,發(fā)布事件。為了防止進(jìn)程崩潰,可以在對(duì)象的事件上注冊(cè)監(jiān)聽器,或使用模塊。注意,模塊已被廢棄。作為最佳實(shí)踐,應(yīng)該始終為事件注冊(cè)監(jiān)聽器。

前言

事件在js中非常的常見(jiàn),不管是瀏覽器還是node,這種事件發(fā)布/訂閱模式的應(yīng)用都是很常見(jiàn)的。至于發(fā)布/訂閱模式和觀察者模式是否是同一種設(shè)計(jì)模式說(shuō)法都有,這里不做具體的討論。在之前的項(xiàng)目中也曾自己實(shí)現(xiàn)過(guò)一個(gè)事件模塊,核心還是一個(gè)EventEmitter。下文就要結(jié)合node中的event模塊分析一下,一個(gè)EventEmitter應(yīng)該如何實(shí)現(xiàn),有什么注意點(diǎn)。
源碼地址
https://github.com/nodejs/nod...

基礎(chǔ)的結(jié)構(gòu)和設(shè)計(jì)

首先第一步就是一個(gè)EventEmitter的類,然后考慮一下這個(gè)類的實(shí)例屬性和實(shí)例方法。
實(shí)例屬性的話最基礎(chǔ)的就是一個(gè)eventMap,可以是一個(gè)空對(duì)象,當(dāng)然也可以這樣創(chuàng)建Object.create(null)。如果需要還可以增加maxListener之類的屬性。
實(shí)例方法的話,最核心的就是add delete emit分別是添加事件,刪除事件,發(fā)布事件。當(dāng)然實(shí)際實(shí)現(xiàn)的時(shí)候,例如count,has,once(一次性添加),preAdd(添加在事件隊(duì)列最前面),這些方法則是可以根據(jù)實(shí)際需求去添加。

具體實(shí)現(xiàn)及注意點(diǎn)

以下代碼均為簡(jiǎn)化的偽代碼

add方法
EventEmitter.prototype.add = function(type, fn) {
    if (!isFunction(fn)) return;//判斷是否在監(jiān)聽中添加的是合法的函數(shù)
    //判斷type是否添加過(guò),添加過(guò)一個(gè)還是多個(gè)函數(shù)
    if (this.event[type]) {
        if (isArray(this.event[type])){
            //如果想要實(shí)現(xiàn)preadd將push改為unshift即可
            this.event[type].push(fn);
        } else {
            //如果想要實(shí)現(xiàn)preadd改變順序
            this.event[type] = [this.event[type], fn];
        }
    } else {
        this.event[type] = fn;
    }
}
once方法

參考一下node的once方法

function onceWrapper(...args) {
  if (!this.fired) {
    this.target.removeListener(this.type, this.wrapFn);
    this.fired = true;
    Reflect.apply(this.listener, this.target, args);
  }
}

function _onceWrap(target, type, listener) {
  var state = { fired: false, wrapFn: undefined, target, type, listener };
  var wrapped = onceWrapper.bind(state);
  wrapped.listener = listener;
  state.wrapFn = wrapped;
  return wrapped;
}

EventEmitter.prototype.once = function once(type, listener) {
  this.on(type, _onceWrap(this, type, listener));
  return this;
};

函數(shù)用onceWrap包裹,運(yùn)行前需要對(duì)添加的監(jiān)聽進(jìn)行移除

delete

很簡(jiǎn)單理清楚幾種邊界情況就可以了

EventEmitter.prototype.delete = function(type, fn) {
    //直接刪除整類監(jiān)聽
    if(fn === undefined){
        this.events[type] && delete this.events[type];
    }else{
        //判斷fn合法性就省了
        if(this.events[type]) {
            if (this.events[type] === fn) {
                delete this.events[type];
            } else {
                for (var i in this.events[type]) {
                    if(this.events[type][i] === fn){
                        if (i === 0) {
                            this.events[type].shift();
                        } else {
                            this.events[type].splice(i,1);
                        }
                    }
                }
                if(this.events[type].length === 1) this.events[type] = this.events[type][0];
            }
        }
    }
    
}
emit
EventEmitter.prototype.emit = function(type) {
    //獲取參數(shù)
    var args = [].slice.call(arguments, 1);
    var handler = events[type];

    if (handler === undefined) return false;

    if (typeof handler === "function") {
        handle.apply(this, args);
    } else {
        var len = handler.length;
        const listeners = arrayClone(handler, len);
        for (var i = 0; i < len; ++i)
             handle[i].apply(this, args);
   }
}

發(fā)布事件有兩個(gè)注意點(diǎn),一個(gè)是注意參數(shù)的保留,另一個(gè)則是上下文,這里上下文是直接取了event實(shí)例的上下文,也可以考慮一下手動(dòng)傳入上下文的形式,或者說(shuō)fn在定義的時(shí)候直接寫成箭頭函數(shù),也可以避免上下文成為eventEmit實(shí)例的上下文。

錯(cuò)誤處理

這里提一下node的event的錯(cuò)誤事件

當(dāng) EventEmitter 實(shí)例中發(fā)生錯(cuò)誤時(shí),會(huì)觸發(fā)一個(gè) "error" 事件。 這在 Node.js 中是特殊情況。
如果 EventEmitter 沒(méi)有為 "error" 事件注冊(cè)至少一個(gè)監(jiān)聽器,則當(dāng) "error" 事件觸發(fā)時(shí),會(huì)拋出錯(cuò)誤、打印堆棧跟蹤、且退出 Node.js 進(jìn)程。
為了防止 Node.js 進(jìn)程崩潰,可以在 process 對(duì)象的 uncaughtException 事件上注冊(cè)監(jiān)聽器,或使用 domain 模塊。 (注意,domain 模塊已被廢棄。)
作為最佳實(shí)踐,應(yīng)該始終為 "error" 事件注冊(cè)監(jiān)聽器。

如果有需要在自己的實(shí)踐中也可以增加一個(gè)錯(cuò)誤處理的機(jī)制,保證event實(shí)例的穩(wěn)定性

總結(jié)

一個(gè)事件訂閱發(fā)布類其實(shí)不難實(shí)現(xiàn),而在node中有很多厲害的類都是繼承的事件類,而之后我會(huì)接著對(duì)node文件系統(tǒng)進(jìn)行學(xué)習(xí)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/93996.html

相關(guān)文章

  • 循序漸進(jìn)教你實(shí)現(xiàn)一個(gè)完整nodeEventEmitter模塊

    摘要:本文從的的使用出發(fā),循序漸進(jìn)的實(shí)現(xiàn)一個(gè)完整的模塊。移除指定事件的某個(gè)監(jiān)聽器,監(jiān)聽器必須是該事件已經(jīng)注冊(cè)過(guò)的監(jiān)聽器的別名移除所有事件的所有監(jiān)聽器,如果指定事件,則移除指定事件的所有監(jiān)聽器。返回指定事件的監(jiān)聽器數(shù)組。 node的事件模塊只包含了一個(gè)類:EventEmitter。這個(gè)類在node的內(nèi)置模塊和第三方模塊中大量使用。EventEmitter本質(zhì)上是一個(gè)觀察者模式的實(shí)現(xiàn),這種模式可...

    sunsmell 評(píng)論0 收藏0
  • 【node不完全指西】EventEmitter (事件發(fā)布/訂閱模式)解析

    摘要:從異步編程解決方案說(shuō)起吧事件發(fā)布訂閱模式模式流程控制庫(kù)事件發(fā)布訂閱模式事件監(jiān)聽器模式是一種廣泛運(yùn)用于異步編程的模式,是回調(diào)函數(shù)的事件話,又稱發(fā)布訂閱模式。 從node異步編程解決方案說(shuō)起吧: 事件發(fā)布/訂閱模式 Promise/deferred模式 流程控制庫(kù) 事件發(fā)布/訂閱模式 事件監(jiān)聽器模式是一種廣泛運(yùn)用于異步編程的模式,是回調(diào)函數(shù)的事件話,又稱發(fā)布/訂閱模式。 主要實(shí)現(xiàn)的幾個(gè)...

    yagami 評(píng)論0 收藏0
  • 【Node事件模塊Events】

    環(huán)境:Node v8.2.1; Npm v5.3.0;OS Windows10 1、 Node事件介紹 Node大多數(shù)核心 API 都采用慣用的異步事件驅(qū)動(dòng)架構(gòu),其中某些類型的對(duì)象(觸發(fā)器)會(huì)周期性地觸發(fā)命名事件來(lái)調(diào)用函數(shù)對(duì)象(監(jiān)聽器)。 所有能觸發(fā)事件的對(duì)象都是 EventEmitter 類的實(shí)例。 這些對(duì)象開放了一個(gè) eventEmitter.on() 函數(shù),允許將一個(gè)或多個(gè)函數(shù)綁定到會(huì)被對(duì)象...

    junnplus 評(píng)論0 收藏0
  • Node 之 Event 模塊

    摘要:為什么把叫做集合而不能稱為嚴(yán)格意義上的對(duì)象,來(lái)看這個(gè)集合的構(gòu)造函數(shù)可以見(jiàn)得,是與處于同一層級(jí)的而非是繼承自,所以說(shuō)由實(shí)例出來(lái)的對(duì)象更加的純凈,并沒(méi)有諸如等方法,更像是一個(gè)集合。 寫在前面 事件的編程方式具有輕量級(jí)、松耦合、只關(guān)注事務(wù)點(diǎn)等優(yōu)勢(shì),在瀏覽器端,有著自己的一套DOM事件機(jī)制,其中含包括這諸如事件冒泡,事件捕獲等;然而Node的事件機(jī)制沒(méi)有事件冒泡等,其原理就是設(shè)計(jì)模式中的觀察者...

    mrli2016 評(píng)論0 收藏0
  • 從觀察者模式到手寫EventEmitter源碼

    摘要:觀察者模式觀察者模式廣泛的應(yīng)用于語(yǔ)言中,瀏覽器事件如鼠標(biāo)單擊,鍵盤事件都是該模式的例子。可以看到,這就是觀察者模式的訂閱方法實(shí)現(xiàn)。小結(jié)通過(guò)創(chuàng)建可觀察的對(duì)象,當(dāng)發(fā)生一個(gè)感興趣的事件時(shí)可將該事件通告給所有觀察者,從而形成松散的耦合。 觀察者模式 觀察者模式(observer)廣泛的應(yīng)用于javascript語(yǔ)言中,瀏覽器事件(如鼠標(biāo)單擊click,鍵盤事件keyDown)都是該模式的例子。...

    cocopeak 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<