Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 56 di 112
  • livello avanzato
Indice lezioni

Il pattern Promise per le operazioni asincrone

Il pattern Promise è un supporto alla programmazione asincrona: per scrivere attività in background che non interrompano il flusso di esecuzione principale.
Il pattern Promise è un supporto alla programmazione asincrona: per scrivere attività in background che non interrompano il flusso di esecuzione principale.
Link copiato negli appunti

Questo pattern non è annoverato tra i design pattern classici, ma ha acquisito un ruolo molto importante nella programmazione JavaScript, in particolare nel supporto alla programmazione asincrona, cioè alla possibilità di eseguire attività in background che non interferiscono con il flusso di elaborazione principale. È ad esempio il caso di richieste dirette al server o ad altri componenti dell'ambiente di esecuzione della nostra applicazione.

Per elaborare il risultato di un'elaborazione asincrona viene normalmente sfruttato il meccanismo delle callback, come mostrato nel seguente esempio:

getMessaggio(function(msg) { console.log(msg.contenuto); })

Ipotizzando che la funzione getMessaggio() richieda in modo asincrono un nuovo messaggio ad un sistema di posta elettronica, il suo parametro rappresenta la funzione di callback da eseguire una volta che il messaggio è stato ottenuto. In questo caso l'operazione eseguita sul messaggio è la semplice visualizzazione del suo contenuto, ma consideriamo il seguente codice:

getMessaggio(
	function(msg) {
		sendMessaggio( msg, "utente@dominio.com",
			function()    { console.log("Messaggio inoltrato"); },
			function(err) { console.log("Si è verificato un errore: " + err.message); } );
	},
	function(err) { console.log("Si è verificato un errore: " + err.message); }
);

In questo esempio la funzione getMessaggio() prevede, oltre al primo parametro, anche un secondo che corrisponde alla funzione di callback da invocare nel caso si sia verificato un errore durante l'acquisizione del messaggio. In aggiunta, dopo aver ricevuto il messaggio, la callback lo inoltra tramite la funzione sendMessaggio(). Anche questa funzione prevede sia la funzione di callback da eseguire dopo aver inviato con successo il messaggio che quella che gestisce la situazione d'errore.

Come possiamo vedere, però, il codice si è talmente complicato da diventare illeggibile (lo diventa certamente di più all'aumentare della complessità delle chiamate).

Per mantenere il codice compatto e facilmente manutenibile possiamo adottare il Promise Pattern.

Secondo questo pattern, una promise è un oggetto che rappresenta il risultato pendente di un'operazione asincrona. Questo oggetto può essere usato per definire le attività da eseguire dopo che l'esecuzione asincrona è terminata.

Seguendo questo pattern, il nostro codice potrebbe trasformarsi in questo modo:

var promise = getMessaggio();
promise.done(sendMessaggio).done(function() {
	console.log("Messaggio inoltrato");
}); 
promise.fail(function(err) {
	console.log("Si è verificato un errore: " + err.message);
});

In sostanza, sia la getMessaggio() che la sendMessaggio() restituiscono una promise, cioè un oggetto che rappresenta l'esito di un'operazione asincrona.

I metodi done() e fail() di una promise consentono di specificare cosa fare dopo aver ottenuto il risultato positivo o negativo dell'elaborazione asincrona. Questi stessi metodi restituiscono delle promise, così possiamo concatenare più done() per mettere in sequenza operazioni asincrone in maniera più leggibile delle callback annidate.

Naturalmente il codice mostrato è solo un possibile esempio, in quanto la sintassi dipenderà da come implementiamo il supporto per le promise o quale libreria utilizziamo. Un esempio di libreria che implementa le promise è Q, ma il pattern è diventato talmente popolare in JavaScript che molte altre librerie e framework, come ad esempio jQuery o AngularJS, forniscono un supporto integrato.

Ti consigliamo anche