• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

    JavaScript EventEmitter 背后的秘密 完整版

    來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:17:19
    文檔

    JavaScript EventEmitter 背后的秘密 完整版

    JavaScript EventEmitter 背后的秘密 完整版:什么是 Event Emitter? Event emitter 聽起來只是觸發(fā)一個(gè)事件,這個(gè)事件任何東西都能監(jiān)聽。 想象一下這樣的場景,在你的異步代碼中,去呼叫一些事件的發(fā)生,以及讓你其他部分都要聽到你的呼叫并且注冊他們的想法。 為了不同的目的,對于 Ev
    推薦度:
    導(dǎo)讀JavaScript EventEmitter 背后的秘密 完整版:什么是 Event Emitter? Event emitter 聽起來只是觸發(fā)一個(gè)事件,這個(gè)事件任何東西都能監(jiān)聽。 想象一下這樣的場景,在你的異步代碼中,去呼叫一些事件的發(fā)生,以及讓你其他部分都要聽到你的呼叫并且注冊他們的想法。 為了不同的目的,對于 Ev

    什么是 Event Emitter?

    Event emitter 聽起來只是觸發(fā)一個(gè)事件,這個(gè)事件任何東西都能監(jiān)聽。

    想象一下這樣的場景,在你的異步代碼中,去“呼叫”一些事件的發(fā)生,以及讓你其他部分都要聽到你的“呼叫”并且注冊他們的想法。

    為了不同的目的,對于 Event Emitter 模式有大量不同的實(shí)現(xiàn),但是基本的想法是為了給一個(gè)框架提供事件的管理以及能夠去訂閱他們。

    在這里,我們的目標(biāo)創(chuàng)建屬于我們自己的 Event Emitter 去理解背后的秘密。所以,讓我們看一下下面的代碼是怎么工作的。

    let input = document.querySelector("input[type="text"]");
    let button = document.querySelector("button");
    let h1 = document.querySelector("h1");
    
    button.addEventListener("click", () => {
     emitter.emit("event:name-changed", { name: input.value });
    });
    
    let emitter = new EventEmitter();
    emitter.subscribe("event:name-changed", data => {
     h1.innerHTML = `Your name is: ${data.name}`;
    });

    讓我們開始。

    class EventEmitter {
     constructor() {
     this.events = {};
     }
    }

    我們先創(chuàng)建一個(gè) EventEmiiter 類以及初始化 events 空對象屬性。這個(gè) events 屬性的目的是為了存儲我們的事件集合,這個(gè) events 對象使用事件名當(dāng)做 key,用訂閱者集合當(dāng)做 value。(可以把每個(gè)訂閱者看作是一個(gè)函數(shù))。

    訂閱函數(shù)

    subscribe(eventName, fn) {
     if (!this.events[eventName]) {
     this.events[eventName] = [];
     }
    
     this.events[eventName].push(fn);
    }

    這個(gè)訂閱函數(shù)獲取事件名稱,在我們之前的例子中,它是 "event:name-changed" 以及傳入一個(gè)回調(diào),當(dāng)有人調(diào)用 emit(或尖叫)事件的時(shí)候調(diào)用回調(diào)。

    在 JavaScript 函數(shù)的優(yōu)點(diǎn)之一是函數(shù)是第一對象,所以我們能像之前我們的訂閱方法一樣,通過函數(shù)作為另一個(gè)函數(shù)的參數(shù)。

    如果未注冊這個(gè)事件,我們需要在第一次為它設(shè)置一個(gè)初始值,事件名稱作為 key 以及初始化一個(gè)空數(shù)組賦值給它,然后我們將函數(shù)放入這個(gè)數(shù)組,以便我們想通過 emit 去調(diào)用這個(gè)事件。

    調(diào)用函數(shù)

    emit(eventName, data) {
     const event = this.events[eventName];
     if (event) {
     event.forEach(fn => {
     fn.call(null, data);
     });
     }
    }

    這個(gè)調(diào)用函數(shù)接受事件名,這個(gè)事件名是我們想“呼叫”的名稱,以及我們想傳遞給這個(gè)事件的數(shù)據(jù)。如果在我們的 events 中存在這個(gè)事件,我們將帶上數(shù)據(jù)循環(huán)調(diào)用所有訂閱的方法。

    使用上面的代碼能做我們所說的全部的事情。但我們?nèi)匀挥幸粋€(gè)問題。當(dāng)我們不再需要它們的時(shí)候,我們需要一種方法來取消注冊這些訂閱,因?yàn)槿绻悴贿@樣做,將造成內(nèi)存泄漏。

    讓我們來解決這個(gè)問題,通過在訂閱函數(shù)中返回一個(gè)取消注冊的方法。

    subscribe(eventName, fn) {
     if (!this.events[eventName]) {
     this.events[eventName] = [];
     }
    
     this.events[eventName].push(fn);
    
     return () => {
     this.events[eventName] = this.events[eventName].filter(eventFn => fn !== eventFn);
     }
    }

    因?yàn)?JavaScript 函數(shù)是第一對象,你能在一個(gè)函數(shù)中返回一個(gè)函數(shù)。因此現(xiàn)在我們能調(diào)用這個(gè)取消注冊函數(shù),如下:

    let unsubscribe = emitter.subscribe("event:name-changed", data => console.log(data));
    
    unsubscribe();

    當(dāng)我們調(diào)用取消注冊函數(shù)的時(shí)候,我們刪除的功能依賴于對訂閱函數(shù)集合的篩選方法(Array filter)。

    和內(nèi)存泄露說再見!👋👋

    你能運(yùn)行這份代碼,所有代碼都在這里。

    html代碼

    <!DOCTYPE html>
    <html>
    <head>
    	<script src="script.js"></script>
    </head>
    <body>
    	<input type="text">
    	<h1></h1>
    	<button>Change name</button>
    </body>
    </html>

    js代碼

    class EventEmitter {
     constructor() {
     this.events = {};
     }
    
     emit(eventName, data) {
     const event = this.events[eventName];
     if (event) {
     event.forEach(fn => {
     fn.call(null, data);
     });
     }
     }
    
     subscribe(eventName, fn) {
     if (!this.events[eventName]) {
     this.events[eventName] = [];
     }
    
     this.events[eventName].push(fn);
     return () => {
     this.events[eventName] = this.events[eventName].filter(eventFn => fn !== eventFn);
     }
     }
    
    
    }
    
    document.addEventListener("DOMContentLoaded", function (event) {
     let input = document.querySelector('input[type="text"]');
     let button = document.querySelector('button');
     let h1 = document.querySelector('h1');
    
     button.addEventListener('click', () => {
     emitter.emit('event:name-changed', { name: input.value });
     });
    
     let emitter = new EventEmitter();
     emitter.subscribe('event:name-changed', data => {
     h1.innerHTML = `Your name is: ${data.name}`;
     });
    });
    

    注:這份代碼可能需要翻墻或者特別慢,所以我放到了 腳本之家 上,大家可以下載EventEmitter-jb51.rar。

    原文出自:https://medium.com/@NetanelBasal/javascript-the-magic-behind-event-emitter-cce3abcbcef9#.nzgbagnxe

    聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    JavaScript EventEmitter 背后的秘密 完整版

    JavaScript EventEmitter 背后的秘密 完整版:什么是 Event Emitter? Event emitter 聽起來只是觸發(fā)一個(gè)事件,這個(gè)事件任何東西都能監(jiān)聽。 想象一下這樣的場景,在你的異步代碼中,去呼叫一些事件的發(fā)生,以及讓你其他部分都要聽到你的呼叫并且注冊他們的想法。 為了不同的目的,對于 Ev
    推薦度:
    標(biāo)簽: 完整版 js event
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 日韩美女18网站久久精品| 热久久国产欧美一区二区精品| 91午夜精品亚洲一区二区三区 | 久久久久亚洲精品天堂| 国产视频精品免费视频| 国产精品手机在线| 久久精品九九亚洲精品| 无码人妻精品一区二区蜜桃百度 | 亚洲国产精品综合久久网络| 国产69精品久久久久99尤物| 国产AV国片精品| 青青草原精品99久久精品66| 亚洲A∨午夜成人片精品网站| 成人国产精品一区二区视频| 99久久精品影院老鸭窝| 久久亚洲国产成人精品性色| 四虎国产精品免费久久| 久久精品18| 精品国产呦系列在线观看免费| 87国产私拍福利精品视频| 久久精品国产亚洲AV无码麻豆| 亚洲色精品vr一区二区三区| 精品国内自产拍在线观看| 国产精品无码永久免费888| 99久久国产综合精品网成人影院| 国产成人精品日本亚洲18图| 91精品全国免费观看青青| 国产午夜无码精品免费看动漫 | 免费人妻精品一区二区三区| 狠狠精品久久久无码中文字幕 | 国产精品成人99久久久久91gav | 成人精品一区二区三区在线观看 | 精品无码一级毛片免费视频观看 | 国产精品99精品视频网站| 精品乱人伦一区二区三区| 国产亚洲美女精品久久久久狼| 2022国产精品自产拍在线观看| 国产成人亚洲综合无码精品| 在线观看自拍少妇精品| 亚洲国产精品特色大片观看完整版| 亚洲欧洲久久久精品|