Async/await in TypeScript

Async/await in TypeScript

Questo articolo spiega async/await in TypeScript.

YouTube Video

Async/await in TypeScript

In TypeScript, async è una parola chiave per descrivere in modo conciso le operazioni asincrone e si comporta in modo simile alla sintassi async/await di JavaScript. Le funzioni async sono progettate per rendere più intuitiva la gestione delle funzioni che restituiscono Promises.

Basi delle funzioni async

Le funzioni dichiarate con la parola chiave async restituiscono sempre un Promise. Ecco un esempio di base:.

1async function fetchData(): Promise<string> {
2    return "Data received";
3}
4
5fetchData().then((data) => console.log(data)); // "Data received"

In questo esempio, poiché la funzione async restituisce sempre un Promise, il valore restituito viene automaticamente risolto utilizzando Promise.resolve. In altre parole, "Data received" diventa un Promise<string> ed è trattato come un'operazione asincrona.

La parola chiave await

La parola chiave await può essere utilizzata solo all'interno di una funzione async. Questo consente di sospendere e attendere il risultato di un Promise prima di continuare con l'esecuzione della funzione.

Nel seguente esempio, l'elaborazione asincrona utilizzando fetch viene scritta con async/await.

 1async function getUserData() {
 2    try {
 3        const response = await fetch("https://codesparklab.com/json/example.json");
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error("Error fetching user data:", error);
 8    }
 9}
10
11getUserData();

In questo esempio, await è utilizzato per attendere il completamento del Promise restituito dalla funzione fetch, e il suo risultato viene assegnato alla variabile response. Inoltre, anche il risultato di response.json() viene atteso.

Gestione degli errori con async/await

Gli errori che si verificano durante l'elaborazione asincrona possono essere intercettati utilizzando la sintassi standard try...catch. Se si verifica un errore nella parte await, quell'errore viene gestito nel blocco catch.

 1async function fetchDataWithErrorHandling() {
 2    try {
 3        const response = await fetch('https://invalid.codesparklab.com/');
 4        if (!response.ok) {
 5            throw new Error(`HTTP error! status: ${response.status}`);
 6        }
 7        const data = await response.json();
 8        console.log(data);
 9    } catch (error) {
10        console.error("Fetch error:", error);
11    }
12}
13
14fetchDataWithErrorHandling();

Nell'esempio sopra, il risultato della funzione fetch viene atteso utilizzando await, e se si verifica un errore, esso viene gestito con try...catch.

Vantaggi di async/await

  1. Elaborazione asincrona intuitiva: Utilizzando async/await, il flusso del codice è più intuitivo rispetto all'uso delle catene di Promise (then o catch), permettendo di scriverlo come un'elaborazione sincrona.

  2. Gestione degli errori semplificata: L'uso di try...catch semplifica la gestione degli errori nelle operazioni asincrone. È possibile scrivere codice più leggibile rispetto all'uso delle catene di Promise.

Valori restituiti dalle funzioni async

Una funzione async restituisce sempre un Promise. Pertanto, anche senza restituire esplicitamente un Promise, è possibile gestire l'elaborazione asincrona utilizzando la parola chiave async.

1async function example() {
2    return 42;
3}
4
5example().then((result) => console.log(result)); // 42

Nel codice sopra, viene restituito un valore sincrono 42, ma essendo all'interno di una funzione async, viene automaticamente convertito in Promise.resolve(42).

Esecuzione sequenziale di funzioni asincrone

Quando si eseguono più funzioni asincrone in successione, è possibile utilizzare await per controllarne l'ordine.

 1async function fetchData(url: string): Promise<any> {
 2    try {
 3        const response = await fetch(url);
 4        return await response.json();
 5    } catch (error) {
 6        console.error("Error fetching user data:", error);
 7    }
 8}
 9
10async function fetchData1(): Promise<any> {
11    return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15    return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function processData() {
19    const data1 = await fetchData1();
20    console.log(data1);
21
22    const data2 = await fetchData2();
23    console.log(data2);
24}
25
26processData();

In questo esempio, fetchData2 viene eseguito dopo aver atteso il completamento di fetchData1. Ciò risulta più leggibile rispetto all'utilizzo di una catena di Promise.

Esecuzione parallela

Se desideri eseguire operazioni asincrone in parallelo, puoi utilizzare Promise.all per gestire più Promise contemporaneamente.

 1async function fetchData(url: string): Promise<any> {
 2    try {
 3        const response = await fetch(url);
 4        return await response.json();
 5    } catch (error) {
 6        console.error("Error fetching user data:", error);
 7    }
 8}
 9
10async function fetchData1(): Promise<any> {
11    return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15    return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function fetchMultipleData() {
19    const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
20    console.log(data1);
21    console.log(data2);
22}
23
24fetchMultipleData();

In questo caso, fetchData1 e fetchData2 vengono eseguiti contemporaneamente, e il processo prosegue dopo che entrambi sono stati risolti. Questo consente di gestire in modo efficiente più operazioni asincrone.

Riepilogo

  • Una funzione async restituisce un Promise, e utilizzando la parola chiave await, puoi attendere il risultato di un'operazione asincrona.
  • Utilizzando try...catch, la gestione degli errori nelle operazioni asincrone diventa più semplice.
  • Utilizzando Promise.all, è possibile eseguire più operazioni asincrone in parallelo.

async/await è ampiamente utilizzato in TypeScript e JavaScript perché consente una descrizione più semplice delle operazioni asincrone.

Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.

YouTube Video