摘要:工具函數(shù)判斷所屬類型判斷是否是或者添加事件監(jiān)聽事件的名稱監(jiān)聽事件對應(yīng)的方法改變的指向執(zhí)行的主體是否只執(zhí)行一次必須是一個函數(shù)如果只執(zhí)行一次將是一次函數(shù)如果已經(jīng)存在監(jiān)聽一個函數(shù)則將是一個數(shù)組如果存在監(jiān)聽多個函數(shù)數(shù)組則類初始化屬性添加事件可執(zhí)行
//工具函數(shù),判斷所屬類型,判斷是否是null或者undefined const toString = Object.prototype.toString; const isType = obj => toString.call(obj).slice(8, -1).toLowerCase(); const isArray = obj => Array.isArray(obj) || isType(obj) === "array"; const isNullOrUndefined = obj => obj === null || obj === undefined; /** * 添加事件 * @param {*} type 監(jiān)聽事件的名稱 * @param {*} fn 監(jiān)聽事件對應(yīng)的方法 * @param {*} context 改變this的指向/執(zhí)行的主體 * @param {*} once 是否只執(zhí)行一次 */ const _addListener = function(type, fn, context, once) { if (typeof fn != "function") { throw new TypeError("fn 必須是一個函數(shù)"); } fn.context = context; fn.once = !!once; const event = this._events[type]; //如果只執(zhí)行一次, this._events[type] 將是一次函數(shù) if (isNullOrUndefined(event)) { this._events[type] = fn; } else if (typeof event === "function") { //如果已經(jīng)存在(監(jiān)聽)一個函數(shù),則this._events[type]將是一個數(shù)組 this._events[type] = [event, fn]; } else if (isArray(event)) { //如果存在(監(jiān)聽)多個函數(shù)(數(shù)組),則push this._events[type].push(fn); } return this; } //EventEmitter類 class EventEmitter { constructor() { //初始化_events屬性 if (isNullOrUndefined(this._events)) { this._events = Object.create(null); } } //添加事件 addListener(type, fn, context) { return _addListener.call(this, type, fn, context); } //可執(zhí)行多次 on(type, fn, context) { return this.addListener(type, fn, context); } //執(zhí)行一次 once(type, fn, context) { return _addListener.call(this, type, fn, context, true); } //事件觸發(fā) emit(type, ...rest) { if (isNullOrUndefined(type)) { throw new Error("emit必須接收至少一個參數(shù)"); } const events = this._events[type]; if (isNullOrUndefined(events)) return false; if (typeof events === "function") { //用call改變this的指向指向events.context主體,否則指向null events.call(events.context || null, rest); //執(zhí)行完畢判斷是否只執(zhí)行一次,是則移除 if (events.once) { this.removeListener(type, events); } } else if (isArray(events)) { events.map(e => { e.call(e.context || null, rest); if (e.once) { this.removeListener(type, e); } }) } return true; } //事件移除 removeListener(type, fn) { if (isNullOrUndefined(this._events)) return this; if (isNullOrUndefined(type)) return this; if (typeof fn !== "function") { throw new Error("fn 必須是一個函數(shù)"); } const events = this._events[type]; if (typeof events === "function") { events === fn && delete this._events[type]; } else { const findIndex = events.findIndex(e => e === fn); if (findIndex === -1) return this; if (findIndex === 0) { events.shift(); } else { events.splice(findIndex, 1); } //如果只剩下一個監(jiān)聽者,則把數(shù)組變?yōu)楹瘮?shù) if (events.length === 1) { this._events[type] = events[0]; } } return this; } //刪除所有事件 removeAllListeners(type) { if (isNullOrUndefined(this._events)) return this; //如果沒有指定type,則刪除全部 if (isNullOrUndefined(type)) this._events = Object.create(null); const events = this._events[type]; if (!isNullOrUndefined(events)) { //判斷是否只剩下最后一個事件 if (Object.keys(this._events).length === 1) { this._events = Object.create(null); } else { delete this._events[type]; } } return this; } //監(jiān)聽隊列 listeners(type) { if (isNullOrUndefined(this._events)) return []; const events = this._events[type]; return isNullOrUndefined(events) ? [] : (typeof events === "function" ? [events] : events.map(o => o)); } //監(jiān)聽者數(shù)量 listenerCount(type) { if (isNullOrUndefined(this._events)) return 0; const events = this._events[type]; return isNullOrUndefined(events) ? 0 : (typeof events === "function" ? 1 : events.length); } eventNames() { if (isNullOrUndefined(this._events)) return []; return Object.keys(this._events); } }
參考自https://www.php.cn/js-tutoria... 作者:php中世界最好的語言
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106735.html
摘要:本文從的的使用出發(fā),循序漸進的實現(xiàn)一個完整的模塊。移除指定事件的某個監(jiān)聽器,監(jiān)聽器必須是該事件已經(jīng)注冊過的監(jiān)聽器的別名移除所有事件的所有監(jiān)聽器,如果指定事件,則移除指定事件的所有監(jiān)聽器。返回指定事件的監(jiān)聽器數(shù)組。 node的事件模塊只包含了一個類:EventEmitter。這個類在node的內(nèi)置模塊和第三方模塊中大量使用。EventEmitter本質(zhì)上是一個觀察者模式的實現(xiàn),這種模式可...
環(huán)境:Node v8.2.1; Npm v5.3.0;OS Windows10 1、 Node事件介紹 Node大多數(shù)核心 API 都采用慣用的異步事件驅(qū)動架構(gòu),其中某些類型的對象(觸發(fā)器)會周期性地觸發(fā)命名事件來調(diào)用函數(shù)對象(監(jiān)聽器)。 所有能觸發(fā)事件的對象都是 EventEmitter 類的實例。 這些對象開放了一個 eventEmitter.on() 函數(shù),允許將一個或多個函數(shù)綁定到會被對象...
摘要:從異步編程解決方案說起吧事件發(fā)布訂閱模式模式流程控制庫事件發(fā)布訂閱模式事件監(jiān)聽器模式是一種廣泛運用于異步編程的模式,是回調(diào)函數(shù)的事件話,又稱發(fā)布訂閱模式。 從node異步編程解決方案說起吧: 事件發(fā)布/訂閱模式 Promise/deferred模式 流程控制庫 事件發(fā)布/訂閱模式 事件監(jiān)聽器模式是一種廣泛運用于異步編程的模式,是回調(diào)函數(shù)的事件話,又稱發(fā)布/訂閱模式。 主要實現(xiàn)的幾個...
摘要:超過會有警告輸出。實例默認(rèn)的某個事件最大監(jiān)聽者的數(shù)量,默認(rèn)是。事件監(jiān)聽數(shù)量是檢測內(nèi)存泄露的一個標(biāo)準(zhǔn)一個維度。例如同一個實例類型事件個監(jiān)聽者,類型事件個監(jiān)聽者,這個并不會有告警。 1. 環(huán)境 node 8.11.3 2. 基本使用 // 01.js const EventEmitter = require(events); class MyEmitter extends EventE...
摘要:打印的參數(shù)分別為移除的監(jiān)聽事件和該事件的句柄函數(shù)默認(rèn)情況下,每個事件可以注冊最多個監(jiān)聽器。返回已注冊監(jiān)聽器的事件名數(shù)組。值設(shè)為或表示不限制監(jiān)聽器的數(shù)量。持續(xù)地記錄返回一個數(shù)組,只包含綁定的監(jiān)聽器。 [github地址:https://github.com/ABCDdouyae...] events 事件觸發(fā)器 大多數(shù) Node.js 核心 API 構(gòu)建于慣用的異步事件驅(qū)動架構(gòu),其中某些...
摘要:打印的參數(shù)分別為移除的監(jiān)聽事件和該事件的句柄函數(shù)默認(rèn)情況下,每個事件可以注冊最多個監(jiān)聽器。返回已注冊監(jiān)聽器的事件名數(shù)組。值設(shè)為或表示不限制監(jiān)聽器的數(shù)量。持續(xù)地記錄返回一個數(shù)組,只包含綁定的監(jiān)聽器。 [github地址:https://github.com/ABCDdouyae...] events 事件觸發(fā)器 大多數(shù) Node.js 核心 API 構(gòu)建于慣用的異步事件驅(qū)動架構(gòu),其中某些...
閱讀 2699·2021-11-23 09:51
閱讀 3274·2021-11-22 14:44
閱讀 4618·2021-11-22 09:34
閱讀 5284·2021-10-08 10:14
閱讀 2587·2021-09-22 15:47
閱讀 3543·2021-09-22 15:40
閱讀 1539·2019-08-30 15:44
閱讀 1646·2019-08-28 18:23