Perché il mio codice Node.js con async/await non esegue in ordine?

👤 Iniziato da @scoutfarina30
📅 14/07/2025 07:30
📁 Programmazione 🌐 IT
Avatar di scoutfarina30
Ragazzi, sono alle prime armi con Node.js e sto combattendo con async/await! Ho scritto una funzione semplice che legge un file, ma i log non rispettano la sequenza che mi aspetto. Uso Node v18.0.0 e il codice è questo:

```javascript
async function leggiFile() {
const fs = require('fs').promises;
console.log('Inizio lettura');
const dati = await fs.readFile('test.txt', 'utf8');
console.log('Finito lettura:', dati);
}

console.log('Prima della funzione');
leggiFile();
console.log('Dopo la funzione');
```
Mi aspetto che stampi:
1. Prima della funzione
2. Inizio lettura
3. Finito lettura
4. Dopo la funzione
Invece ottengo:
1. Prima della funzione
2. Dopo la funzione
3. Inizio lettura
4. Finito lettura
Ho già provato a aggiungere `await` alla chiamata di `leggiFile()`, ma poi mi dà errore "await is only valid in async function". Ho controllato documentazioni e tutorial ma non capisco dove sbaglio. Qualcuno ha riscontrato lo stesso problema? Consigli per far rispettare l'ordine di esecuzione?
Avatar di enricolombardo1
Eh sì, l'async/await in Node.js è una fregatura all'inizio! Il problema è che quando chiami `leggiFile()` senza `await`, Node.js non aspetta che finisca e passa subito a `console.log('Dopo la funzione')`. Quell'errore "await is only valid in async function" ti sta dicendo che puoi usare `await` solo dentro funzioni async.

Per sistemare, incapsula il codice principale in una IIFE asincrona:
```javascript
(async () => {
console.log('Prima della funzione');
await leggiFile();
console.log('Dopo la funzione');
})();
```

Oppure usa `.then()` sulla chiamata:
```javascript
console.log('Prima della funzione');
leggiFile().then(() => console.log('Dopo la funzione'));
```

La IIFE è più pulita secondo me. Ricorda: `await` sospende *solo* l'esecuzione all'interno della funzione async in cui è chiamato. Se usi Node.js 14.8+ puoi anche usare `await` a top-level con moduli ES! In bocca al lupo con l'asincronia, vedrai che diventerà un'ossessione 😉
Avatar di filomenadagostino
Ciao scoutfarina30! Capisco la frustrazione, l'asincronia in Node.js è un osso duro all'inizio 😅 Il problema è che **`leggiFile()` ritorna una Promise**, ma quando la chiami senza `await`, l'esecuzione prosegue subito al `console.log('Dopo la funzione')`.

@enricolombardo1 ha dato ottimi consigli! Aggiungo due cose:
1. Se usi moduli ES (metti `"type": "module"` in package.json), puoi usare **await a top-level** senza IIFE:
```javascript
console.log('Prima');
await leggiFile();
console.log('Dopo');
```
Con Node.js v18 funziona!

2. Occhio a **dipendenze nascoste**: se `test.txt` è grande o il disco è lento, il ritardo nell'I/O "sballa" l'ordine. Per debug, aggiungi un `console.time('lettura')` prima dell'`await` e `console.timeEnd()` dopo per misurare il delay.

Sei sulla strada giusta comunque! Anch'io ho sbattuto la testa su ste cose, poi tutto "clicca" e diventa divertente 💪 Continua così!
Avatar di elideconti8
Hai beccato in pieno il nodo (ehm) dell'esecuzione non bloccante in Node.js. Il punto è che **`await` funziona solo dentro una funzione `async`**, quindi quando chiami `leggiFile()` fuori da un contesto async, l'interprete parte con la lettura del file (che è I/O) ma *non aspetta* che finisca: ecco perché "Dopo la funzione" esce prima.

Per forzare l'ordine, puoi usare una IIFE async come ti hanno detto, ma se non vuoi infilare tutto in un modulo ES puoi anche aggiungere un `.then()` dopo `leggiFile()` per collegare l'esecuzione:
```javascript
leggiFile().then(() => console.log('Dopo la funzione'));
```
Alternativa: se il file è piccolo, puoi usare `fs.readFileSync()` che è sincrono, ma non è consigliato in ambienti produttivi perché blocca tutto.

Ricorda: in JavaScript la parte *sincrona* (i log fuori da async) gira prima di qualsiasi callback asincrono, anche se sembra "sotto" nel codice. È normale che all'inizio ti mandi in tilt, ma una volta che capisci l'event loop diventa un gioco di pazienza. Aspettare è dura, ma in Node.js paga sempre 😄.
Avatar di scoutfarina30
Ah, GENIO! Adesso è tutto chiarissimo! Quello che mi mancava era proprio capire che **`await` non aspetta fuori dall'async** 😅. La spiegazione sull'event loop mi ha aperto gli occhi!

Proverò subito con il `.then()` per non bloccare tutto, grazie per l'alternativa pratica. E hai ragione: meglio evitare `readFileSync` in produzione, non voglio far piangere il server 💥.

Sì, l'asincrono è un salto mentale, ma con questi chiarimenti ora mi sento meno in balia delle callback! Grazie mille, davvero illuminante ✨.
Avatar di sarabernardi
Sono così felice che tu abbia finalmente capito il meccanismo dell'async/await, @scoutfarina30! 😊 Anch'io ricordo quando mi sono scontrata con questo problema la prima volta... è stato come cercare di risolvere un puzzle senza avere tutti i pezzi giusti!

Adesso che hai compreso il concetto, ti consiglio di approfondire un po' la gestione delle Promise e dell'event loop. Un buon libro che potrebbe aiutarti è "Node.js 8 the Right Way" di Jim Wilson. Non solo ti aiuterà con l'asincronismo, ma ti darà anche una visione più completa di Node.js.

E, parlando di cose completamente diverse, dopo aver risolto questo problema, dovresti premiarti con una visita in una buona cartoleria... io sto già pensando a quali quaderni colorati comprarmi! 📚💜. Tornando a noi, se hai altre domande o hai bisogno di ulteriore aiuto, non esitare a chiedere. Buona fortuna con il tuo progetto!
Avatar di simeonebianchi70
@sarabernardi hai ragione, il libro di Jim Wilson è una miniera di informazioni! Tuttavia, se vuoi un'introduzione più immediata, ti consiglio "JavaScript: The Good Parts" di Douglas Crockford. È un classico che ti aiuterà a capire le basi del linguaggio in modo più approfondito. Per quanto riguarda l'event loop, ho trovato molto utile "You Don't Know JS" di Kyle Simpson, che spiega con chiarezza i concetti fondamentali. E riguardo alla cartoleria, hai proprio ragione! Dopo tutte queste ore davanti allo schermo, un po' di carta e inchiostro fresco non guasta mai. 📖✍️

Per quanto riguarda il tuo progetto, Scout, non esitare a chiedere se hai bisogno di ulteriori chiarimenti. E ricorda, ogni sfida è un'opportunità per imparare qualcosa di nuovo. Buona fortuna!

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!