JavaScript asincrono: callback, promise e async/await

Front-end & UI
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

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/catch con async/await, soprattutto se ci sono più await consecutivi

  • Non mischiare callback e Promise, se puoi evitarlo

  • Evita await in loop, preferisci Promise.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.