101 - Funzioni async/await
Le funzioni async/await sono l’incubo di tutte le persone che iniziano a lavorare con tecnologie come Javascript, ma in realtà sono tanto facili quanto ordinare una pizza con un’app di consegna a domicilio.
Comprendere una funzione asincrona e farla cooperare con altre funzioni, può sembrare difficile, ma non è assolutamente così.
In questo articolo, diamo quindi un’occhiata a come rendere le funzioni async/await super facili!
Che cos’è un’attività asincrona?
Un’attività asincrona consente di completare altre attività mentre l’attività asincrona è ancora in fase di completamento. In altre parole, questa funzione verrà eseguita in maniera indipendente rispetto alle altre e manderà una notifica o un evento quando avrà terminato.
Prendiamo come esempio l’ordine di una pizza su una qualsiasi app di consegna a domicilio.
Scegli la pizza, mandi l’ordine (async) e chiudi l’app. Nel frattempo che attendi la conferma (await), accendi la TV e scegli che film vedere la sera, mentre la struttura avvia la preparazione dell’ordine e cucina la tua pizza (async).
Un altro esempio? Una funzione asincrona è quando lavi il pavimento della cucina (async) e mentre aspetti che si asciughi (await), vai a mettere su una lavatrice (async).
Torniamo al nostro esempio principale e iniziamo a scrivere un po’ di codice!
Hands on!
Diciamo che vogliamo ordinare una pizza in quel ristorante napoletano sotto casa che ci piace tanto. Il primo passo è aprire l’app e scegliere la pizza; una volta inviato l’ordine, scegliamo il film per la serata e aspettiamo che la pizza sia pronta.
Quando il rider sarà partito dalla struttura, riceveremo un messaggio e aspetteremo con ansia che il campanello suoni. Ci siamo?
Ok, procediamo!
// Funzione per ordinare la pizza
const orderPizza = async () => {
console.log('Pizza has been chosen and order has been sent! Wait for the confirmation');
const response = await orderConfirmed();
console.log(response);
}
// Funzione asincrona che aspetta la conferma dell'ordine
const orderConfirmed= async () => {
return new Promise(resolve => setTimeout(() => {
resolve('Thanks for your order! Pizza is on its way to the oven!')
}, 3000));
}
// Funzioni accessorie
const getPizza = () => console.log('Order pizza.');
const chooseMovie= () => console.log('Opening Netflix and choosing a movie for tonight.');
const watchTV = () => console.log('Watching movie.');
// Eseguiamo le funzioni
getPizza();
orderPizza();
chooseMovie();
watchTV();
// Output
Order pizza.
Pizza has been chosen and order has been sent! Wait for the confirmation
Opening Netflix and choosing a movie for tonight.
Watching movie.
Thanks for your order! Pizza is on its way to the oven!
ll risultato è quanto prodotto dalle funzioni asincrone: mentre scegliamo la pizza e ordiniamo (funzione orderPizza()), noi ci sediamo sul divano pronti per un po’ di Netflix (funzione chooseMovie() e watchMovie()) e aspettiamo che l’ordine venga confermato.
Sembra paradossale, ma in Javascript funziona allo stesso modo.
Breve sintassi sull’uso delle funzioni async/await. Credits to Il Blog di Andrea Merlin (https://amerlin.keantex.com)
Notare però che quando si attende una risposta da una funzione asincrona, è necessario chiamarla all’interno di un’altra funzione che è sempre asincrona. Questo è ciò che vediamo sopra quando all’interno di orderPizza() viene chiamato orderConfirmed().
Due punti chiave da ricordare:
- Javascript NON attende il completamento di una funzione asincrona come orderPizza() prima di passare alle attività che seguono come watchTV() e chooseMovie().
- Javascript attenderà una funzione asincrona come orderConfirmed() per completare e restituire i dati prima di passare all’attività successiva all’interno di una funzione asincrona padre. Lo vediamo nel momento in cui ci viene restituita la risposta finale.
E se l’esempio della pizza è chiaro, passiamo al caso in cui abbiamo bisogno di dati che devono essere restituiti da un servizio esterno, ed eseguire delle operazioni solo quando questi dati saranno pronti!
Definiamo una funzione asincrona (riga 1) che, recuperati dei dati da un’API esterna, attende che questi dati siano restituiti (riga 3) e se la response ottenuta è positiva (riga 4) , li estrae in una nuova variabile (riga 5) li stampa a nei log (riga 6).
const getTheData = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) throw Error();
const data = await response.json();
console.log(data);
console.log('End!')
} catch (err) {
console.error(err);
}
}
getTheData();
console.log('Begin');
// Output
Begin.
// data
End!
Che dici, è più chiaro ora come si usano le funzioni async/await?