亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript EventEmitter 背后的秘密 完整版

2019-11-19 14:05:11
字體:
來源:轉載
供稿:網友

什么是 Event Emitter?

Event emitter 聽起來只是觸發一個事件,這個事件任何東西都能監聽。

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

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

在這里,我們的目標創建屬于我們自己的 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 = {};  }}

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

訂閱函數

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

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

在 JavaScript 函數的優點之一是函數是第一對象,所以我們能像之前我們的訂閱方法一樣,通過函數作為另一個函數的參數。

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

調用函數

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

這個調用函數接受事件名,這個事件名是我們想“呼叫”的名稱,以及我們想傳遞給這個事件的數據。如果在我們的 events 中存在這個事件,我們將帶上數據循環調用所有訂閱的方法。

使用上面的代碼能做我們所說的全部的事情。但我們仍然有一個問題。當我們不再需要它們的時候,我們需要一種方法來取消注冊這些訂閱,因為如果你不這樣做,將造成內存泄漏。

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

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);  }}

因為 JavaScript 函數是第一對象,你能在一個函數中返回一個函數。因此現在我們能調用這個取消注冊函數,如下:

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

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

和內存泄露說再見!👋👋

你能運行這份代碼,所有代碼都在這里。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品影片在线观看| 欧美主播福利视频| 亚洲欧洲午夜一线一品| 国外日韩电影在线观看| 91精品国产高清| 成人免费观看49www在线观看| 日本高清+成人网在线观看| 欧美最近摘花xxxx摘花| 韩国欧美亚洲国产| 亚洲国产成人精品一区二区| 国产精品视频公开费视频| 国产精品美乳在线观看| 精品视频久久久| 亚洲综合一区二区不卡| 亚洲欧美精品中文字幕在线| 久久天天躁狠狠躁夜夜爽蜜月| 日日狠狠久久偷偷四色综合免费| 国产这里只有精品| 久久99久久99精品中文字幕| 久久资源免费视频| 国产成人激情小视频| 欧美精品日韩www.p站| 国产盗摄xxxx视频xxx69| 国产美女久久久| 91精品中国老女人| 欧美另类交人妖| 亚洲japanese制服美女| 丝袜美腿精品国产二区| 国产亚洲精品成人av久久ww| 2019中文在线观看| 欧美中文字幕在线观看| 久久久久久伊人| 91在线观看免费高清完整版在线观看| 欧美极品在线播放| 久久久天堂国产精品女人| 亚洲一区二区黄| 欧美日韩一区二区免费在线观看| 亚洲精品资源在线| 欧美成人免费小视频| 亚洲在线视频福利| 日韩国产在线看| 国产成人精品网站| 欧美大全免费观看电视剧大泉洋| 日韩av在线免费| 欧美性受xxxx黑人猛交| 91久久精品国产91久久| 欧美激情精品久久久久久| 欧美午夜视频一区二区| 日本国产一区二区三区| 精品性高朝久久久久久久| 精品国产91乱高清在线观看| 久久精品国产v日韩v亚洲| 日韩电影中文字幕av| 亚洲美女www午夜| 8x拔播拔播x8国产精品| 美女久久久久久久| 精品国产欧美一区二区三区成人| 国产成+人+综合+亚洲欧洲| 欧美视频在线观看免费网址| 欧美小视频在线| 亚洲成人网av| 日韩欧美有码在线| 97**国产露脸精品国产| 一区二区三区四区在线观看视频| 欧美丰满少妇xxxx| 亚洲天堂男人天堂女人天堂| 欧美另类交人妖| 国产精品亚洲美女av网站| 国产欧美一区二区三区在线看| 日韩欧美亚洲范冰冰与中字| 国产精品香蕉国产| 孩xxxx性bbbb欧美| 欧美日本黄视频| 亚洲一区二区福利| 欧美日韩国产色| 77777少妇光屁股久久一区| 久久久精品电影| 亚洲国产私拍精品国模在线观看| 91久久在线播放| 亚洲精品国产美女| 成人福利视频在线观看| 国产成人精品a视频一区www| 欧美性xxxx极品高清hd直播| 欧美专区日韩视频| 自拍偷拍亚洲区| 国产在线精品一区免费香蕉| 日韩欧美亚洲一二三区| 国产精品久久久久久久久久久不卡| 久久精品国产精品| 国产精品扒开腿做爽爽爽的视频| 有码中文亚洲精品| 亚洲成人免费网站| 成人国产精品一区| 亚洲一级一级97网| 国产97在线|日韩| 26uuu久久噜噜噜噜| 亚洲午夜小视频| 欧美成年人在线观看| 97视频免费看| 久久精品一偷一偷国产| 久久伊人91精品综合网站| 国产在线观看不卡| 亚洲天堂男人的天堂| 国产精品一区久久久| 九九视频直播综合网| 国产精品丝袜久久久久久不卡| 国产成人午夜视频网址| 91大神在线播放精品| 国产精品入口福利| 欧美成人久久久| 国产亚洲视频在线观看| 一本久久综合亚洲鲁鲁| 亚洲第一区中文字幕| 中文字幕欧美日韩在线| 欧美午夜片在线免费观看| 日韩av色在线| 欧美大片免费观看在线观看网站推荐| 国产一区二区三区精品久久久| 久久精品夜夜夜夜夜久久| 亚洲免费中文字幕| 久久在线免费视频| 欧美丝袜美女中出在线| 91精品国产91久久久久久久久| 亚洲系列中文字幕| 欧美激情第99页| 欧美亚洲激情在线| 日韩国产在线播放| 国产香蕉精品视频一区二区三区| 久久亚洲精品中文字幕冲田杏梨| 亚洲一区二区在线| 久久免费国产精品1| 精品国产一区二区三区四区在线观看| 亚洲色图35p| 国内免费精品永久在线视频| 欧美日韩国产精品一区二区三区四区| 狠狠色狠色综合曰曰| 亚洲精品综合久久中文字幕| 日本不卡免费高清视频| 欧美精品久久一区二区| 日韩精品免费看| 久久久久北条麻妃免费看| 在线不卡国产精品| 国产欧美日韩中文字幕在线| 情事1991在线| 久久天天躁狠狠躁老女人| 91精品国产777在线观看| 成人美女免费网站视频| 91精品国产777在线观看| 最近2019中文字幕在线高清| 欧美性猛交99久久久久99按摩| 日韩精品在线视频美女| 国产日韩欧美夫妻视频在线观看| 国产精品视频一区二区高潮| 亚洲少妇中文在线| 国产精品自拍小视频| 国产精品青青在线观看爽香蕉| 欧美夫妻性生活xx| 麻豆一区二区在线观看| 91精品综合视频| 精品视频—区二区三区免费| 成人福利免费观看| 久久久精品久久久久| 国产精品电影在线观看| 91福利视频网|