Tutto sugli Eventi in Node.js
Cosa sono, come funzionano e come usarli

Tempo di lettura: 4 minuti
Cosa sono gli eventi su Node.js e come usarli

Se ti trovi qui vuol dire che stai imparando Node.js, l’ambiente di sviluppo Javascript basato su eventi. In questo articolo parleremo di cosa sono gli eventi in Node, di come mettersi in ascolto di un particolare evento  ma sopratutto di come emettere un evento!

Ricapitoliamo un attimo come funziona Node.js, innanzitutto esiste un solo thread e le operazioni vengono gestite in maniera non bloccante (trovi maggiori dettagli qui). In questo modo possiamo gestire operazioni in background (come il caricamento di un file, il download di una pagina web, l’avvio di un server web, e così via) e quando l’operazione è completa viene richiamata una funzione di callback.

Come funziona nodejs modello bloccante non bloccante, programmazione sincrona e asincrona
Programmazione asincrona e modello non bloccante

Questo è ciò che lo rende potente ma anche un po’ più difficile da capire, perché ci costringe ad usare molte funzioni di callback che sfruttano proprio gli eventi.

Gli eventi sono la base di Node.js!

In questo articolo ci soffermeremo su come funziono gli venti in Node.js, in particolare, come possiamo ascoltare e creare eventi. Qualsiasi sviluppatore Node.js che si rispetti dovrebbe sapere come farlo, quindi cominciamo!

Mettersi in ascolto di particolari eventi (listening)

Sorpresa! Nel 99% dei casi dovresti già sapere come metterti in ascolti gli eventi in Javascript.

Non dirmi che non hai mai usato una libreria come jQuery per “catturare” eventi sulla tua pagina web!

Ad esempio:

$("canvas").on("mouseleave", function() { ... });

Con questo tipo di istruzione,  richiede di eseguire una funzione di callback quando il mouse lascia un elemento <canvas>. Questo viene definito collegando un evento al DOM della pagina.

Con Node.js, il principio è esattamente lo stesso!

Moltissimi oggetti oggetti Node.js emette eventi,  la particolarità è che tutti ereditano ciò da un oggetto EventEmitter fornito da Node.

Per esempio, prendiamo il modulo http che abbiamo usato per creare il nostro web server, anche lui include un oggetto Server che emette eventi. Nella documentazione di Node puoi trovarli riportati cosi:

eventi-documentazione-nodejs
Eventi che gli oggetti Nodejs emettono (documentazione ufficiale)

Come si possono metterci in ascolto di questi eventi?

Supponendo che, per esempio, vogliamo gestire l’evento di chiusura che si verifica quando il server viene fermato. È sufficiente usare il metodo on() ed inserire:

  • Il nome dell’evento che volete leggere (in questo caso “close”).
  • La funzione di callback da chiamare quando si verifica l’evento.

Esempio:

server.on('close', function() {
  // Fai qualcosa quando il server si ferma
})

Ecco un esempio più completo: lanciamo il server e lo arrestiamo subito dopo. Ci mettiamo in ascolto dell’evento close che si verifica quando il server viene fermato. Quando il server si fermerà visualizziamo un messaggio nella console.

var http = require('http');

var server = http.createServer(function(req, res) {
  res.writeHead(200);
  res.end('Ciao a tutti!');
});
server.on('close', function() {
  // Siamo in ascolto dell'evento di chiusura
  console.log('Addio!');
});
// Avviamo il server
server.listen(8080);
// Stoppialo il server. Questo attiverà l'evento close
server.close();

Aspetta un momento… createServer() contiene già una funzione callback. Perché non usiamo on() qui?

Ottima osservazione! In realtà si tratta di un’abbreviazione del codice. Se rileggi la sezione CreateServer nella documentazione mostrata nel codice Web precedente, ti accorgerai che la funzione callback che gli inviamo come parametro viene aggiunta automaticamente all’evento “request”.

Quindi questo codice:

var server = http.createServer(function(req, res) { });

Può essere scritto anche in questa maniera più prolissa:

// Equivale al codice precedente
var server = http.createServer();
server.on('request', function(req, res) { });

In breve, gli eventi sono ovunque, non si possono evitare!

Alcuni sono leggermente “nascosti” come in questo caso, ma è importante sapere cosa sta accadendo dietro.

È anche possibile mettersi in ascolto più volte per lo stesso evento. Ti basterà richiamare due volte la funzione on() per lo stesso evento ed entrambe le funzioni callback saranno richiamate quando l’evento avrà luogo, facile.

Trasmettere (o emettere) eventi con EventEmitter

Se vuoi trasmettere un evento, è molto semplice, basta includere il modulo EventEmitter e creare un oggetto basato su EventEmitter.

var EventEmitter = require('events').EventEmitter;

var game = new EventEmitter();

Quindi, per trasmettere un evento nel codice, è necessario che l’oggetto basato su EventEmitter richiami il metodo emit(), passando:

  • Il nome dell’evento che si vuole gestire (es:”gameover”), è a tua scelta.
  • Uno o più parametri (opzionale).

Qui, sto generando un evento “gameover” e mando un messaggio al destinatario dell’evento:

game.emit('gameover', 'You lose!');

Se vuoi metterti in ascolto dell’evento devi fare:

game.on('gameover', function(message) { });

Ecco il codice completo per testare la trasmissione degli eventi:

var EventEmitter = require('events').EventEmitter;

var game = new EventEmitter();

game.on('gameover', function(message){
  console.log(message);
});

game.emit('gameover', 'Hai perso!');

Ammetto che come esempio è un po’ troppo semplice…

Questo codice è limitato alla trasmissione di un evento, in realtà, gli eventi vengono trasmessi dalle funzioni costruite all’interno di altre funzioni – è qui che Node.js offre enormi possibilità.

Come puoi vedere, il principio non è complicato da capire!

Non dimenticare che è possibile inviare tutti i paramentri necessari per la funzione callback semplicemente emettendo altri parametri:

// Invia il nome e l'età di un nuovo giocatore è appena entrato in gioco
game.emit('newplayer', 'Mario', 35);

Conclusioni: ascoltare eventi con Node.js e come emetterli

  • Tutte le applicazioni Node.js sono basate su un meccanismo di eventi, che determina quale funzione sarà successivamente chiamata.
  • Con il metodo on(), è possibile riprodurre un evento e dire quale funzione deve essere richiamata al verificarsi dell’evento.
  • Con il metodo emit() è possibile creare il proprio evento e quindi attivare le funzioni che ascoltano l’evento.

 


L’articolo che hai appena letto fa parte di una lunga serie di guide e tutorial tradotte in italiano e distribuite gratuitamente. In particolare questo articolo si basa sui testi inglesi di Mathieu Nebra (Ultra fast applications using Node.js), con licenza CC BY-NC-SA. Questo articolo è sotto la stessa licenza.