Ogni volta che clicchi un bottone, carichi dati da un’API o aspetti una risposta da un server, dietro le quinte JavaScript lavora in modalità asincrona.
Ma cosa significa davvero?
E perché esistono tre modi diversi per gestire l’asincronia: callback, promise e async/await?
In questo articolo facciamo chiarezza con esempi pratici, spiegazioni semplici e consigli su quando usare l’uno o l’altro approccio. Perché l’asincronia, in JavaScript, non è (più) un mistero.
1. Perché JavaScript è asincrono?
JavaScript gira su un solo thread. Se ogni operazione (es. lettura file, richiesta HTTP) bloccasse l’esecuzione, il browser sarebbe inutilizzabile.
Per questo usa un modello basato su eventi e callback, che gli permette di:
-
Lanciare un'operazione lenta
-
Continuare a fare altro
-
Eseguire il codice "di risposta" solo quando l’operazione è completata
Questo è il cuore dell’asincronia.
2. Le callback: il primo approccio (e i suoi limiti)
Una callback è una funzione passata come argomento a un’altra funzione.
Esempio:
function saluta(nome, callback) {
console.log("Ciao " + nome);
callback();
}
saluta("Loredana", () => {
console.log("Benvenuta nel mondo JS!");
});
Molto usate, ma… se le callback si annidano:
richiesta1(() => {
richiesta2(() => {
richiesta3(() => {
// callback hell!
});
});
});
Questo problema è noto come callback hell o “piramide del caos”.
3. Le Promise: una svolta per la leggibilità
Le Promise sono oggetti che rappresentano un valore che potrebbe arrivare in futuro.
Esempio:
const dati = fetch("https://api.esempio.com")
.then(risposta => risposta.json())
.then(json => console.log(json))
.catch(errore => console.error("Errore!", errore));
Vantaggi:
-
Catena leggibile con
.then() -
Gestione errori con
.catch() -
Separazione tra logica e dati
Le Promise hanno migliorato molto la gestione asincrona, ma per catene lunghe risultano ancora verbose.
4. Async/Await: la sintassi moderna
Dal 2017 JavaScript supporta async/await, una sintassi che semplifica le Promise rendendo il codice più leggibile:
async function caricaDati() {
try {
const risposta = await fetch("https://api.esempio.com");
const json = await risposta.json();
console.log(json);
} catch (errore) {
console.error("Errore nel caricamento", errore);
}
}
Con await, JavaScript “aspetta” che la Promise sia risolta prima di proseguire, senza bloccare il thread principale.
5. Quale usare? Callback, Promise o Async/Await?
| Metodo | Quando usarlo |
|---|---|
| Callback | Operazioni semplici, librerie vecchie |
| Promise | Flussi intermedi, catene moderate |
| Async/Await | Progetti moderni, codice leggibile e testabile |
✅ Oggi la scelta consigliata è async/await, anche per chi è alle prime armi: la sintassi è più chiara e simile a quella sincrona.
6. Debug e buone pratiche
-
Usa
try/catchcon async/await, soprattutto se ci sono piùawaitconsecutivi -
Non mischiare callback e Promise, se puoi evitarlo
-
Evita
awaitin loop, preferisciPromise.all()per parallelo -
Commenta il flusso asincrono, per chi legge dopo
7. Risorse utili per approfondire
Conclusione
L’asincronia è il cuore pulsante di JavaScript. Capirla ti aiuta a:
-
scrivere codice robusto
-
evitare bug “fantasma”
-
migliorare le performance
Nel 2025, async/await è lo standard, ma conoscere anche callback e Promise ti rende una sviluppatrice (o sviluppatore) completa.