Sådan bruges begivenheder i Node.js på den rigtige måde

Før begivenhedsdrevet programmering blev populær, var den standard måde at kommunikere mellem forskellige dele af en applikation ret ligetil: en komponent, der ønskede at sende en besked til en anden, påkaldte eksplicit en metode på den komponent. Men begivenhedsdrevet kode er skrevet til at reagere snarere end at blive kaldt .

Fordelene ved Eventing

Denne tilgang får vores komponenter til at blive langt mere afkoblet . Når vi fortsætter med at skrive en ansøgning, identificerer vi begivenheder undervejs. Vi fyrer dem på det rigtige tidspunkt og knytter en eller flere begivenhedslyttere til hver enkelt. Udvidelse af funktionalitet bliver meget lettere. Vi kan tilføje flere lyttere til en bestemt begivenhed. Vi manipulerer ikke med de eksisterende lyttere eller den del af applikationen, hvor begivenheden blev fyret fra. Hvad vi taler om er observatørmønsteret.

Design af en begivenhedsdrevet arkitektur

At identificere begivenheder er ret vigtigt. Vi ønsker ikke at ende med at skulle fjerne / erstatte eksisterende begivenheder fra systemet. Dette kan tvinge os til at slette / ændre et hvilket som helst antal lyttere, der var knyttet til begivenheden. Det generelle princip, jeg bruger, er kun at overveje at fyre en begivenhed, når en enhed af forretningslogik afslutter udførelsen.

Så sig, at du vil sende en masse forskellige e-mails ud efter en brugers registrering. Nu kan selve registreringsprocessen involvere mange komplicerede trin og forespørgsler. Men set ud fra et forretningsmæssigt synspunkt er det et skridt. Og hver af de e-mails, der skal sendes, er også individuelle trin. Så det ville være fornuftigt at affyre en begivenhed, så snart tilmeldingen er afsluttet. Vi har flere lyttere knyttet til det, som hver er ansvarlige for at sende en type e-mail.

Knudens asynkrone, hændelsesdrevne arkitektur har visse slags objekter kaldet "emittere". De udsender navngivne begivenheder, der får funktioner kaldet "lyttere" til at blive påberåbt. Alle objekter, der udsender begivenheder, er forekomster af klassen EventEmitter. Ved hjælp af det kan vi oprette vores egne begivenheder:

Et eksempel

Lad os bruge det indbyggede begivenhedsmodul (som jeg opfordrer dig til at tjekke detaljeret) for at få adgang til EventEmitter.

Dette er den del af applikationen, hvor vores server modtager en HTTP-anmodning, gemmer en ny bruger og udsender en begivenhed:

Og et separat modul, hvor vi vedhæfter en lytter:

Det er en god praksis at adskille politik fra implementering. I dette tilfælde betyder politik, hvilke lyttere der abonnerer på, hvilke begivenheder. Implementering betyder lytterne selv.

Denne adskillelse gør det også muligt for lytteren at blive genanvendelig. Det kan knyttes til andre begivenheder, der sender den samme besked (et brugerobjekt). Det er også vigtigt at nævne, at når flere lyttere er knyttet til en enkelt begivenhed, udføres de synkront og i den rækkefølge, de blev vedhæftet . Derfor someOtherListenerkører efter sendEmailOnRegistrationfærdig udførelse.

Men hvis du vil have dine lyttere til at køre asynkront, kan du simpelthen pakke deres implementeringer med setImmediatesådan:

Hold dine lyttere rene

Hold dig til princippet om et enkelt ansvar, når du skriver lyttere. En lytter skal kun gøre en ting og gøre det godt. Undgå for eksempel at skrive for mange betingelser inden for en lytter, der beslutter, hvad de skal gøre, afhængigt af de data (meddelelse), der blev sendt af begivenheden. Det ville være meget mere passende at bruge forskellige begivenheder i så fald:

Løsnelse af lyttere eksplicit, når det er nødvendigt

I det foregående eksempel var vores lyttere helt uafhængige funktioner. Men i tilfælde, hvor en lytter er forbundet med et objekt (det er en metode), skal den manuelt løsnes fra de begivenheder, den havde abonneret på. Ellers indsamles objektet aldrig skrald, da en del af objektet (lytteren) fortsat refereres til af et eksternt objekt (emitteren). Dermed muligheden for en hukommelseslækage.

For eksempel, hvis vi bygger en chatapplikation, og vi ønsker ansvaret for at vise en underretning, når en ny besked ankommer til et chatrum, som en bruger har oprettet forbindelse til, skal ligge inden for selve brugerobjektet, kan vi gøre dette:

Når brugeren lukker hans / hendes fane eller mister deres internetforbindelse i et stykke tid, vil vi naturligvis muligvis udløse et tilbagekald på serversiden, der underretter de andre brugere om, at en af ​​dem bare gik offline. På dette tidspunkt giver det selvfølgelig ingen mening displayNewMessageNotificationat blive påberåbt til offlinebrugeren. Det kaldes fortsat på nye beskeder, medmindre vi fjerner det eksplicit. Hvis vi ikke gør det, bortset fra det unødvendige opkald, forbliver brugerobjektet også i hukommelsen på ubestemt tid. Så sørg for at ringe disconnectFromChatroomtil din serverside-tilbagekald, der udføres, når en bruger går offline.

Pas på

Den løse kobling i begivenhedsdrevne arkitekturer kan også føre til øget kompleksitet, hvis vi ikke er forsigtige. Det kan være svært at holde styr på afhængigheder i vores system. Vores ansøgning bliver særlig tilbøjelig til dette problem, hvis vi begynder at udsende begivenheder fra lyttere. Dette kan muligvis udløse kæder af uventede begivenheder.