I Node.js mange av objektene i miljøet sender ut hendelser, for eksempel sender en TCP -server en type hendelse koble hver gang en ny klient kobler seg til eller en strøm av filer sender ut informasjon hver gang en informasjon blir lest.
Dette i Node.js er det som kalles hendelsesemittere, som gir utviklere muligheten til å abonnere på hendelser, der den abonnerer på en funksjon Ring tilbake som vil bli påkalt hver gang en hendelse i hendelsesutsenderen skjer. Vi kan til og med lage våre egne hendelsesutsendere takket være pseudoklassen EventEmitter.
For å komme inn med hendelsesutsendere må vi imidlertid først være klare om noen begreper, for eksempel noen mønstre for disse funksjonene, typer hendelser og til og med lytterne.
KravFor å utføre øvelsene som er foreslått i denne opplæringen må vi ha en funksjonell installasjon av Node.js i systemet vårt, kan vi ta en titt på denne opplæringen før vi fortsetter å fordype oss i den. Det er også viktig å ha tilgang til en rik tekstredigerer for å kode eksemplene. Vi kan bruke det vi føler oss komfortable med, men for enkel brukervennlighet anbefaler vi Sublim tekst o NotePad ++ som også har plugins for syntaksen JavaScript Y HTML.
Mønster for tilbakeringing
Asynkron programmering bruker ikke retur av verdier i funksjonene for å angi at funksjonen nettopp er fullført, men den påkaller den berømte tilbakeringingen etter at operasjonen er fullført, slik at programmet vårt kan fortsette der JavaScript Jeg leder til denne typen programmering, la oss se et eksempel i Ikke gi som leser en fil og laster innholdet i minnet:
var fs = krever ('fs'); fs.readFile ('file.txt', function (err, fileContent) {if (err) {throw err;} console.log ('File content:', fileContent.toString ());});Det vi gjør her er at vi sender en anonym funksjon som det andre argumentet for funksjonen fs.readFile, og hvordan kan vi se at det første argumentet for tilbakeringingsfunksjonen er et feilobjekt, som vil ha en forekomst av feilklassen hvis det oppstår en feil.
Mønster for hendelsesutsenderen
Den forrige stilen fungerer perfekt når vi vil varsle om at en funksjon som vi utfører, fullfører arbeidet, men i tilfelle flere hendelser finner sted under denne utførelsen eller mange ganger, vil denne stilen ikke fungere som vi vil. For eksempel, hvis vi vil bli varslet hver gang informasjonen er tilgjengelig i kontakten, en funksjon av typen Ring tilbake standard vil ikke hjelpe oss mye, men det er her hendelsesutsenderen kan hjelpe oss.
Hendelsesutsenderen er ikke annet enn et objekt som, som navnet indikerer, avgir en hendelse, der a lytteren det er en del av koden som binder seg til denne senderen og lytter til visse typer hendelser, for eksempel:
var req = http.request (alternativer, funksjon (respons) {response.on ("data", funksjon (data) {console.log ("Noen svarsdata", data);}); response.on ("end" , funksjon () {console.log ("fullført svar");});}); req.end ();Dette er en rent forklarende kode, der vi kan se noen av trinnene for å sende en forespørsel HTTP til en ekstern server, men det lar oss se hvordan svarobjektet er en hendelsesutsender, som ikke bare kan avgi data Y slutt men andre typer hendelser.
Typer hendelser
I følge det forrige eksemplet kunne vi se at hendelsene som sendes ut alltid har en type, som er representert med en streng, i dette tilfellet "data"Y"slutt”, Som vil være vilkårlige strenger utpekt av hendelsesutstederen.
Hendelsesemitteren er et generisk grensesnitt som betjener alle typer hendelser, men det er et spesielt tilfelle i implementeringen av Ikke gi og det er hendelsen feil, hvor hver hendelse i miljøet vil avgi en hendelse av denne typen hver gang det oppstår en feil, og hvis utvikleren velger å ikke lytte til denne typen hendelser og det oppstår en feil, vil hendelsesutsenderen legge merke til det og gjøre et unntak i dette tilfellet . La oss se i følgende kode hvordan vi kan simulere denne oppførselen:
var em = new (require ('events'). EventEmitter) (); em.emit ('hendelse1'); em.emit ('feil', ny feil ('min feil'));Hvis vi kjører den gjennom konsollen, kan vi se hvordan Ikke gi forteller oss at vi ikke håndterer feilen, og genererer dermed et ufanget unntak:
Siden vi har sett hvordan hendelser oppfører seg på en generell måte, la oss se hvordan vi bruker hendelsesemitter -API.
Bruker hendelsesemitter -API
Ethvert objekt som implementerer hendelsesemittermønsteret implementerer en serie hendelser som vi kan se nedenfor:
.addListener - .onDenne metoden lar oss legge til en lytter til en hendelsestype.
.elleveMed denne metoden kan vi binde en lytter til en hendelsestype, gitt at den vil bli kalt minst en gang.
.removeEventListenerDenne metoden lar oss fjerne en lytter fra en gitt hendelse.
.removeAllEventListenersTil slutt hjelper denne metoden oss med å fjerne alle lyttere for en gitt type hendelse.
Etter å ha sett hva funksjonen til hver av disse er, la oss se hvordan vi bruker dem i programmene våre.
Bruke .addListener () eller .on () i tilbakeringing
Ved å spesifisere en hendelsestype og en funksjon Ring tilbake, kan vi registrere handlingen som skal utføres når en bestemt hendelse oppstår. For eksempel, hvis vi vil bli informert om at en del av dataene er tilgjengelige og avgi en hendelse med typedata, kan vi gjøre følgende:
function ReceiveData (data) {console.log ("Dataene ble innhentet:% j", data); } readFlow.addListener ("data", ReceiveData);Vi kan også bruke metoden .on () som bare er en snarvei, la oss se ekvivalenten til den forrige koden:
function ReceiveData (data) {console.log ("Dataene ble innhentet:% j", data); } readFlow.on ("data", mottaksdata);Vi kan til og med legge til flere lyttere for at hendelsene våre skal lytte til samme type hendelse på samme sender, for eksempel:
I dette eksemplet er det som er gjort, å binde to funksjoner til datatypehendelsen, og der når datahendelsen er sendt ut, blir begge strengene skrevet ut. Det er viktig å merke seg at hendelsesutstederen er ansvarlig for å ringe alle lyttere registrert for en hendelsestype, og den vil ringe dem i rekkefølgen de ble registrert i, noe som betyr følgende:
- En lytter kan ikke ringes umiddelbart etter at hendelsen er sendt ut, det er mulig at andre lyttere blir ringt opp før.
- Å ikke fange unntak er usunn oppførsel for koden vår, så hvis noen av disse lytterne kaster en feil og ikke blir fanget, er det mulig at noen lyttere ikke blir kalt, hvor vi kan illustrere dette i følgende eksempel:
Hvor i dette eksemplet den andre lytteren ikke vil bli påkalt siden den første kastet en feil.
Bruke .removeListener ()
Hvis vi når som helst ikke lenger vil bli informert om endringer i en bestemt hendelse eller et bestemt objekt, kan vi stoppe opptaket ved å spesifisere hendelsestypen og tilbakeringingsfunksjonen som følger:
Bruke .once ()
I tilfelle søknaden vår lytter etter en hendelse som vil skje minst en gang, eller hvis vi bare er interessert i at den skal skje bare én gang, kan vi bruke .elleve(), som legger til lytteren og fjerner den når den første hendelsen skjer:
Bruke .removeAllListeners ()
Til slutt kan vi fjerne alle lyttere for en bestemt hendelsestype fra en hendelsesemitter som følger:
issuer.removeAllListeners (type);
Oppretter hendelsesemitteren
Hendelsesutsenderen gir oss en generisk måte å lage grensesnitt på, siden vi binder hendelser i stedet for funksjoner, noe som gjør programmet vårt mer fleksibelt, selv om vi ønsker å bruke mønsteret til Node.js Gjennom vår applikasjon kan vi lage en pseudoklasse og arve fra EventEmitter som følger:
util = krever ('util'); var EventEmitter = require ('events'). EventEmitter; var MyClass = function () {} util.inherits (MyClass, EventEmitter);På denne måten metodene for EventEmitter De vil være tilgjengelige for vår forekomst, og vi kan bruke dem uten problemer og på denne måten Klassen min kan avgi hendelser:
MyClass.prototype.someMethod = function () {this.emit ("egendefinert hendelse", "argument 1", "argument 2"); };Her når noen metode kalles i forekomsten av Klassen min, eksemplet sender ut en hendelse kalt tilpasset arrangement, der den igjen sender ut to forskjellige data, argument 1 og argument 2, som vil bli sendt til hendelseslytterne. Til slutt i tilfeller av Klassen min på klientsiden kan du lytte til tilpasset arrangement som følger:
var MyClass = ny MyClass (); MyClass.on ('egendefinert hendelse', funksjon (str1, str2) {console.log ('Egendefinert hendelse lyttet med argumenter str1% s og str2% s!', Str1, str2);});Som vi kan se, hjelper bruken av hendelser sammen med hendelsesemitteren oss med å kommunisere med applikasjonen vår, og slik avsluttet vi denne opplæringen, der vi klarte å gå utover asynkron programmering og bruke praksis som hjelper oss å opprettholde en standard og optimal mønster. for våre applikasjoner.