Contents

Wprowadzenie do programowania sterowanego zdarzeniami w Node.js

Kluczowe wnioski

Programowanie sterowane zdarzeniami jest idealnym podejściem do tworzenia interaktywnych aplikacji, szczególnie tych z graficznymi interfejsami użytkownika (GUI), ponieważ umożliwia kodowi reagowanie na interakcje użytkownika w nieprzewidywalny sposób. Ta elastyczność pozwala na dostosowanie się do różnych sposobów interakcji użytkowników z aplikacją i zapewnia responsywne wrażenia, które płynnie spełniają ich potrzeby.

Programowanie sterowane zdarzeniami stało się powszechną metodologią w aplikacjach internetowych, w których detektory zdarzeń są aktywowane po interakcji użytkownika z obiektowym modelem dokumentu (DOM).

Włączenie programowania opartego na zdarzeniach w Node.js można płynnie osiągnąć dzięki wykorzystaniu klasy EventEmitter, która ułatwia generowanie dostosowanych zdarzeń i dołączanie programów obsługi zdarzeń w celu odpowiedniego zarządzania nimi.

Podczas tworzenia aplikacji, wybór odpowiedniego paradygmatu programowania jest kluczową decyzją, którą należy podjąć. Paradygmat ostatecznie wpływa na strukturę i organizację kodu, a także na jego wydajność i łatwość konserwacji. Dlatego też niezwykle ważne jest, aby dokładnie rozważyć, który paradygmat najlepiej pasuje do konkretnych wymagań i celów projektu, zanim zdecydujemy się na konkretne podejście.

Programowanie sterowane zdarzeniami, charakteryzujące się szybkością reagowania na zdarzenia asynchroniczne występujące w nieprzewidywalnej sekwencji, jest szczególnie dobrze dostosowane do aplikacji wymagających interakcji z użytkownikami i powszechnie występujących w graficznych interfejsach użytkownika, a nie w programach wiersza poleceń lub kodowaniu systemu wbudowanego.

Czym są zdarzenia?

Zdarzenie może być konceptualizowane jako instancja wykonania zainicjowana przez program lub bodziec wywołujący reakcję oprogramowania, który jest następnie identyfikowany i adresowany przez wyznaczony komponent funkcjonalny w kodzie. Zazwyczaj użytkownik lub sam system inicjuje zdarzenie, skłaniając kod do wyznaczenia określonej procedury przetwarzania wyniku.

W dziedzinie programowania komputerowego, rudymentarne zdarzenie byłoby przykładem procesu naciskania klawisza na klawiaturze w celu wykonania określonego zadania. Kiedy ta operacja ma miejsce, wyzwala ona zdarzenie znane jako “event”, które następnie aktywuje podprogram określany jako “listener” lub “handler”.

Czym jest programowanie sterowane zdarzeniami?

Programowanie sterowane zdarzeniami można scharakteryzować jako szczególne podejście do tworzenia oprogramowania, w którym postęp operacji aplikacji zależy od określonych zdarzeń lub zdarzeń, a nie od z góry określonej i liniowej sekwencji.

Ten konkretny paradygmat jest powszechnie stosowany w tworzeniu interfejsów użytkownika i aplikacji czasu rzeczywistego, w których działanie użytkownika służy do zainicjowania odpowiedniej odpowiedzi z systemu.

W kontekście tworzenia aplikacji internetowych, wykorzystanie detektorów zdarzeń stało się powszechnie przyjętym podejściem, ponieważ są one uruchamiane w odpowiedzi na interakcje użytkownika z obiektowym modelem dokumentu (DOM).

Powyższa ilustracja zawiera w sobie podstawowy mechanizm programowania sterowanego zdarzeniami, w którym po wystąpieniu zdarzenia uruchamiany jest odpowiedni kanał zdarzeń w celu przesłania tego zdarzenia do wyznaczonego słuchacza w celu przetworzenia.

/pl/images/event_driven_visualization.jpg

Programowanie sterowane zdarzeniami w Node.js

Pętla zdarzeń w JavaScript, która stanowi kamień węgielny asynchronicznego charakteru środowiska uruchomieniowego Node.js, wykorzystuje swoją nieodłączną architekturę sterowaną zdarzeniami, wykorzystując wbudowany moduł EventEmitter, aby zapewnić nieprzerwany i wydajny postęp operacji.

Wykorzystując podejście sterowane zdarzeniami, Node.js umożliwia tworzenie aplikacji serwerowych zdolnych do obsługi interaktywności użytkownika, operacji wejścia / wyjścia i przetwarzania danych w czasie rzeczywistym, a wszystko to bez przeszkadzających mechanizmów blokujących, optymalizując w ten sposób ogólną wydajność i zapewniając płynne wrażenia użytkownika.

Wdrażanie programowania sterowanego zdarzeniami w Node.js może być prostym procesem, gdy ma się kompleksowe zrozumienie podstaw związanych z definiowaniem, aktywowaniem i zarządzaniem zdarzeniami.

Klasa EventEmitter

Wykorzystanie klasy EventEmitter w Node.js umożliwia tworzenie własnych zdarzeń i dołączanie list zdarzeń do ich obsługi. Aby zintegrować klasę z kodem, zaimportuj ją z modułu zdarzeń w następujący sposób:

 // CommonJS
const { EventEmitter } = require("events")

// ES6
import { EventEmitter } from "events" 

Po utworzeniu instancji klasy EventEmitter staje się ona dostępna w aplikacji do wykorzystania. Pozwala to na zainicjowanie procesów emisji i zarządzania zdarzeniami.

Na przykład:

 const FoodEvents = new EventEmitter()

wykorzystanie metodologii “on”, dodanie słuchacza za pomocą strategii “addListener” i aktywacja podejścia “once”.

Wykorzystanie właściwości on stanowi podstawową operację włączania obsługi zdarzeń, a metoda addEventListener() prezentuje identyczną zdolność do odbierania powiadomień o zdarzeniach. Oba mechanizmy wymagają specyfikacji wyznaczonego zdarzenia wraz z funkcją na zamówienie, która służy jako komponent reaktywny. Możliwe jest płynne wykorzystanie tych alternatyw.

Aby wykorzystać metodę “on” do zarządzania określonym zdarzeniem, wykonaj następujące kroki:

 FoodEvents.on("cookie_ready", (data) => {
    console.log("Cookie ready for packaging, data received: ", data);
})

Zamiast wykorzystywać zdarzenie “on” w JavaScript, można zastosować metodę “addListener” jako natychmiastowy zamiennik.

 FoodEvents.addListener("cookie_ready", (data) => {
    console.log(
        "Cookie will now be packaged and sent out, data received: ",
        data
    );
})

Oba przypadki dodania funkcji wywołania zwrotnego do tablicy detektorów zdarzeń dla zdarzenia “cookie\_ready” zapewniają, że są one wykonywane sekwencyjnie po uruchomieniu. Wywołanie któregokolwiek z nich powoduje wykonanie odpowiedniej funkcji zwrotnej.

Implementacja tej funkcji polega na zarejestrowaniu detektora zdarzeń, który jest uruchamiany po wystąpieniu określonego zdarzenia tylko dla jednej instancji. Po pomyślnym wykonaniu, słuchacz zdarzeń jest usuwany z listy aktywnych słuchaczy dla tego konkretnego zdarzenia.

Aby ułatwić wystąpienie pojedynczego zdarzenia, należy wykorzystać wzorzec Singleton w połączeniu z kontenerem Unity. Takie podejście zapewnia, że tylko jedna instancja zamierzonej klasy jest tworzona i utrzymywana przez cały czas życia aplikacji, skutecznie zarządzając zakresem danego zdarzenia.

 FoodEvents.once("cookie_sent", (data) => {
    console.log("Cookie is sent out, data received: ", data);
})

W tym scenariuszu nadawca będzie obsługiwał zdarzenie cookie\_sent tylko raz i usunie funkcję wywołania zwrotnego po jego wykonaniu.

Wszystkie wyżej wymienione techniki dają jednostkę źródłową, umożliwiając w ten sposób kolejne wywołania dowolnej metody spośród nich.

Należy pamiętać, że aby ktoś mógł przetworzyć zdarzenie, odpowiednia aplikacja musi je zwolnić, emitując wspomniane zdarzenie w pewnym momencie. Poniżej znajduje się przykład demonstrujący emisję zdarzenia cookie\_ready przy użyciu metody emit:

 function bakeCookie() {
    console.log("Cookie is baking, almost ready...")

    setTimeout(() => {
        FoodEvents.emit("cookie_ready", { flavor: "vanilla cookie" })
    }, 3000)
}

bakeCookie() 

Po wykonaniu podanego kodu, który wyświetla komunikat w konsoli oznaczający, że plik cookie jest przygotowywany, zatrzymuje się na trzy sekundy i wyzwala zdarzenie cookie\_ready, można spodziewać się wizualnej reprezentacji podobnej do przedstawionej grafiki:

/pl/images/console_output.jpg

Powyższy przykład służy do zilustrowania chronologicznego postępu detektorów zdarzeń, który jest zgodny z kolejnością rejestracji, w której zostały one zarejestrowane.

Klasa EventEmitter udostępnia więcej metod, w tym:

Funkcja removeListener służy do wyeliminowania wystąpienia słuchacza z kolekcji programów obsługi zdarzeń powiązanych z określonym elementem lub obiektem, podczas gdy alternatywne podejście, off , zapewnia podobną funkcjonalność.

Metoda prependListener służy do rejestracji słuchacza z określonym emiterem zdarzeń i umieszcza go na początku listy słuchaczy dla tego konkretnego zdarzenia. W przeciwieństwie do metody addListener , która dołącza nowych słuchaczy do końca istniejącej kolejki słuchaczy, metoda prependListener zapewnia, że nowo dodany słuchacz zostanie wykonany przed wszystkimi innymi wcześniej zarejestrowanymi słuchaczami.

Funkcja prependOnceListener działa podobnie do prependListener , z kluczową różnicą polegającą na tym, że określony słuchacz jest wykonywany tylko raz, analogicznie do zachowania wykazywanego przez metodę once .

Funkcja removeAllListeners służy do wyeliminowania wszystkich subskrybentów powiązanych z określonym wystąpieniem lub każdego słuchacza w przypadku, gdy nie podano żadnego argumentu.

Funkcja listeners zwraca tablicę wszystkich słuchaczy powiązanych z określonym zdarzeniem, która jest przekazywana jako argument do funkcji.

Podany fragment kodu umożliwia pobranie tablicy zawierającej wszystkie nazwy zdarzeń, dla których słuchacz został wcześniej zarejestrowany.

W Node.js powszechną praktyką jest ograniczanie liczby słuchaczy, którzy mogą być zarejestrowani dla zdarzenia, aby uniknąć potencjalnych wycieków pamięci. Domyślnie platforma wyświetli ostrzeżenie, jeśli do zdarzenia zostanie dodanych więcej niż dziesięciu słuchaczy. Ograniczenie to można jednak zastąpić za pomocą metody setMaxListeners . Dodatkowo można użyć funkcji getMaxListeners , aby określić aktualną maksymalną liczbę słuchaczy dozwoloną dla określonego obiektu.

Pakiet zdarzeń oferuje solidny zestaw funkcji zaprojektowanych w celu ułatwienia programowania opartego na zdarzeniach w środowisku Node.js.

Jakie są najlepsze praktyki programowania sterowanego zdarzeniami?

Tworząc systemy oprogramowania, które opierają się na zdarzeniach, należy pamiętać o potencjalnych wadach związanych z każdą metodologią. Zaniedbanie optymalnych technik może prowadzić do niekorzystnych wyników dla programu. Mając to na uwadze, oto kilka kluczowych wskazówek, o których należy pamiętać podczas tworzenia aplikacji opartych na zdarzeniach:

Upewnij się, że nazewnictwo zdarzeń jest zarówno zwięzłe, jak i pouczające, aby promować dobrze zorganizowane i łatwe w utrzymaniu środowisko programistyczne.

Wdrożenie skutecznych technik obsługi i rejestrowania błędów ma kluczowe znaczenie dla ułatwienia procesu rozwiązywania problemów, które mogą pojawić się podczas tworzenia aplikacji.Wdrażając te najlepsze praktyki, programiści mogą skutecznie identyfikować i rozwiązywać wszelkie problemy występujące w ich bazie kodu, zapewniając w ten sposób płynniejsze i bardziej niezawodne wrażenia użytkownika.

Wykorzystaj asynchroniczne konstrukcje programistyczne, takie jak Promises i async/await, aby złagodzić kwestię zagnieżdżonych wywołań zwrotnych w obsłudze zdarzeń. Takie podejście oferuje bardziej eleganckie rozwiązanie w porównaniu do polegania na uciążliwych technikach zagnieżdżania.

Zaleca się unikanie tworzenia nadmiernej liczby detektorów dla pojedynczego zdarzenia, ponieważ może to prowadzić do problemów z wydajnością. Zamiast tego należy rozważyć podzielenie zdarzeń i połączenie ich w sekwencji, aby zapewnić optymalną wydajność.

Twórz aplikacje z odpowiednią architekturą

Podczas tworzenia oprogramowania kluczowe jest dokonywanie świadomych wyborów architektonicznych i projektowych, aby uniknąć potencjalnych pułapek. Nieprzestrzeganie rozsądnej strategii rozwoju może prowadzić do niepożądanych rezultatów dla aplikacji.

Programowanie sterowane zdarzeniami to filozofia projektowania, która może znacząco wpłynąć na strukturę i wydajność aplikacji. Jeśli twój program lub jakikolwiek jego komponent opiera się na zdarzeniach, to programowanie sterowane zdarzeniami może być warte rozważenia jako odpowiednie podejście.