În Node.js multe dintre obiectele prezente în mediu emit evenimente, de exemplu un server TCP emite un eveniment de tip conectați de fiecare dată când un client nou se conectează sau un flux de fișiere emite informații de fiecare dată când este citită o informație.
Aceasta în Node.js este ceea ce se numește emițătoare de evenimente, care permit dezvoltatorilor posibilitatea de a abona evenimente, unde subscrie o funcție sună din nou care va fi invocat de fiecare dată când are loc un eveniment în emițătorul de evenimente. Putem chiar să creăm proprii emițători de evenimente datorită pseudo-clasei EventEmitter.
Cu toate acestea, pentru a intra cu emitenții de evenimente, trebuie mai întâi să fim clari cu privire la unele concepte, cum ar fi unele tipare ale acestor funcții, tipurile de evenimente și chiar ascultătorii.
CerințePentru a efectua exercițiile propuse în acest tutorial trebuie să avem o instalare funcțională de Node.js în sistemul nostru, putem arunca o privire asupra acestui tutorial înainte de a continua să aprofundăm în el. De asemenea, este important să aveți acces la un editor de text bogat pentru a codifica exemplele, putem folosi orice ne simțim confortabil, totuși, pentru ușurința sa de utilizare, vă recomandăm Text sublim o NotePad ++ care are și pluginuri pentru sintaxă JavaScript Da HTML.
Model pentru apeluri de apel
Programarea asincronă nu folosește returnarea valorilor în funcții pentru a indica faptul că acea funcție tocmai s-a terminat, dar invocă celebrul apel invers după finalizarea operației, astfel încât programul nostru să poată continua, unde JavaScript Am condus la acest tip de programare, să vedem un exemplu în Nu da care citește un fișier și încarcă conținutul acestuia în memorie:
var fs = require ('fs'); fs.readFile ('file.txt', function (err, fileContent) {if (err) {throw err;} console.log ('File content:', fileContent.toString ());});Ceea ce facem aici este că trimitem o funcție anonimă ca al doilea argument al funcției fs.readFile, și cum putem vedea primul argument al funcției de apel invers este un obiect de eroare, care va avea o instanță din clasa Error dacă apare o eroare.
Model pentru emițătorul evenimentului
Stilul anterior funcționează perfect atunci când vrem să anunțăm că o funcție pe care o executăm își termină activitatea, dar în cazul în care au loc mai multe evenimente în timpul acestei execuții sau de multe ori, acest stil nu va funcționa așa cum dorim. De exemplu, dacă vrem să fim anunțați de fiecare dată când informațiile sunt disponibile în socket, o funcție de tip sună din nou standardul nu ne va ajuta prea mult, dar aici ne poate ajuta emițătorul de evenimente.
Emițătorul de evenimente nu este altceva decât un obiect care, așa cum indică și numele său, emite un eveniment, unde a ascultător face parte din cod care se leagă de acest emițător și ascultă anumite tipuri de evenimente, cum ar fi:
var req = http.request (opțiuni, funcție (răspuns) {response.on ("date", funcție (date) {console.log ("Unele date de răspuns", date);}); response.on ("sfârșit" , function () {console.log ("răspuns completat");});}); req.end ();Acesta este un cod pur explicativ, unde putem vedea câțiva pași pentru a face o cerere HTTP către un server la distanță, dar ne permite să vedem cum obiectul de răspuns este un emițător de evenimente, care poate emite nu numai date Da Sfârșit dar și alte tipuri de evenimente deopotrivă.
Tipuri de evenimente
Conform exemplului anterior am putut vedea că evenimentele emise au întotdeauna un tip, care este reprezentat de un șir, în acest caz "date„Y”Sfârșit”, Care vor fi șiruri arbitrare desemnate de emitentul evenimentului.
Emițătorul de evenimente este o interfață generică care servește orice tip de eveniment, dar există un caz special în implementarea Nu da și este evenimentul eroare, în cazul în care fiecare eveniment din mediu va emite un eveniment de acest tip de fiecare dată când apare o eroare și dacă dezvoltatorul alege să nu asculte acest tip de eveniment și apare o eroare, emițătorul de evenimente îl va observa și va ridica o excepție în acest caz . Să vedem în următorul cod cum putem simula acest comportament:
var em = new (require ('events'). EventEmitter) (); em.emit („eveniment1”); em.emit („eroare”, eroare nouă („eroarea mea”));Dacă îl rulăm prin consolă, putem vedea cum Nu da ne spune că nu gestionăm eroarea, generând astfel o excepție neaprinsă:
Deoarece am văzut cum se comportă evenimentele într-un mod general, să vedem cum folosim API-ul emițătorului de evenimente.
Folosind API-ul emițătorului de evenimente
Orice obiect care implementează modelul emițătorului de evenimente implementează o serie de evenimente așa cum putem vedea mai jos:
.addListener - .onAceastă metodă ne permite să adăugăm un ascultător la un tip de eveniment.
.unsprezeceCu această metodă putem lega un ascultător de un tip de eveniment dat fiind că acesta va fi apelat cel puțin o dată.
.removeEventListenerAceastă metodă ne va permite să eliminăm un ascultător din orice eveniment dat.
.removeAllEventListenersÎn cele din urmă, această metodă ne ajută să eliminăm toți ascultătorii pentru un anumit tip de eveniment.
După ce am văzut deja care este funcția fiecăruia dintre acestea, să vedem cum le folosim în cadrul programelor noastre.
Folosind .addListener () sau .on () în callbacks
Prin specificarea unui tip de eveniment și a unei funcții sună din nou, putem înregistra acțiunea de întreprins atunci când apare un anumit eveniment. De exemplu, dacă vrem să fim informați că o parte din date este disponibilă și emitem un eveniment de tip date, putem face următoarele:
funcția receiveData (date) {console.log ("Datele au fost obținute:% j", date); } readFlow.addListener („date”, ReceiveData);Putem folosi și metoda .pe () care este doar o comandă rapidă, să vedem echivalentul codului anterior:
funcția receiveData (date) {console.log ("Datele au fost obținute:% j", date); } readFlow.on („date”, receiveData);Putem adăuga chiar și mai mulți ascultători pentru evenimentele noastre pentru a asculta același tip de eveniment pe același transmițător, de exemplu:
În acest exemplu, ceea ce se face este legarea a două funcții la evenimentul de tip de date și unde, odată ce evenimentul de date este emis, ambele șiruri vor fi tipărite. Este important să rețineți că emitentul evenimentului este responsabil pentru apelarea tuturor ascultători înregistrate pentru un tip de eveniment și le va apela în ordinea în care au fost înregistrate, ceea ce înseamnă următoarele:
- Un ascultător nu poate fi apelat imediat după emiterea evenimentului, este posibil ca alți ascultători să fie chemați înainte.
- Nu prindeți excepții este un comportament nesănătos pentru codul nostru, deci dacă oricare dintre acești ascultători aruncă o eroare și nu este prins, este posibil ca unii ascultători să nu fie chemați, unde putem ilustra acest lucru în următorul exemplu:
În cazul în care în acest exemplu, cel de-al doilea ascultător nu va fi invocat, deoarece primul a aruncat o eroare.
Utilizarea .removeListener ()
Dacă în orice moment nu mai dorim să fim informați cu privire la modificările aduse unui anumit eveniment sau obiect, putem opri înregistrarea acestuia specificând tipul de eveniment și funcția de apel invers după cum urmează:
Folosind .once ()
În cazul în care aplicația noastră ascultă un eveniment care se va întâmpla cel puțin o dată sau dacă suntem interesați să se întâmple doar o singură dată, putem folosi .unsprezece(), care adaugă ascultătorul și îl elimină odată ce apare primul eveniment:
Utilizarea .removeAllListeners ()
În cele din urmă, putem elimina toți ascultătorii pentru un anumit tip de eveniment de la un emițător de evenimente, după cum urmează:
emitent.removeAllListeners (tip);
Crearea emițătorului de evenimente
Emițătorul de evenimente ne oferă un mod generic de a crea interfețe, deoarece suntem obligatorii de evenimente în loc de funcții, făcând programul nostru mai flexibil, chiar dacă dorim să folosim tiparul de Node.js De-a lungul aplicației noastre putem crea o pseudo-clasă și putem moșteni de la EventEmitter după cum urmează:
util = require ('util'); var EventEmitter = require ('events'). EventEmitter; var MyClass = function () {} util.inherits (MyClass, EventEmitter);În acest fel metodele de EventEmitter Ele vor fi disponibile pentru instanța noastră și le putem folosi fără probleme și în acest fel Clasa mea poate emite evenimente:
MyClass.prototype.someMethod = function () {this.emit („eveniment personalizat”, „argument 1”, „argument 2”); };Aici când vreo metodă se numește în cazul Clasa mea, exemplul emite un eveniment numit eveniment personalizat, unde la rândul său emite două date diferite, argumentul 1 și argumentul 2, care vor fi trimise ascultătorilor evenimentului. În cele din urmă în cazurile Clasa mea din partea clientului puteți asculta eveniment personalizat după cum urmează:
var MyClass = new MyClass (); MyClass.on ('eveniment personalizat', funcție (str1, str2) {console.log ('Eveniment personalizat ascultat cu argumente str1% s și str2% s!', Str1, str2);});După cum putem vedea, utilizarea evenimentelor împreună cu emițătorul de evenimente ne ajută să comunicăm cu aplicația noastră și așa am încheiat acest tutorial, în care am putut să depășim programarea asincronă și aplicarea practicilor care ne ajută să menținem un standard și optim pentru aplicațiile noastre.