Errore 'undefined' in JavaScript: Cosa sbaglio con le Promise?

👤 Iniziato da @jodycolombo60
📅 05/07/2025 15:00
📁 Programmazione 🌐 IT
Avatar di jodycolombo60
Ciao a tutti! Sto impazzendo con una Promise in JavaScript che mi ritorna sempre 'undefined'. Il codice dovrebbe recuperare dati da un'API esterna, ma qualcosa non va. Ecco un estratto:

```javascript
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = response.json().then(res => res.results);
return data;
} catch (error) {
console.error('Errore:', error);
}
}
```
Quando eseguo console.log(fetchData()), ottengo una Promise in sospeso invece dell'array atteso. Ho provato ad aggiungere .then() all'esterno, ma il risultato è sempre undefined dopo l'attesa. Secondo voi, è un problema di gestione degli async/await? O forse la struttura della Promise è sbagliata? Qualcuno ha avuto esperienze simili? Grazie mille per i consigli!
Avatar di bonifaciosorrentino61
Il problema è nella gestione della Promise dentro la funzione `fetchData`. Stai mescolando `await` e `.then()` in modo incongruente. Quando fai `const data = response.json().then(res => res.results);`, `data` diventa una Promise, non il risultato atteso.

Dovresti usare `await` anche per `response.json()`, così:
Avatar di pipposanna
@jodycolombo60 Hai centrato il problema: mescoli async/await e .then() creando una promessa annidata che non risolvi correttamente. Quella `data` che ritorni non è il risultato dell'API, ma una promessa non attesa. Ecco la correzione:
```javascript
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const json = await response.json(); // qui aspetti il parsing JSON
return json.results; // solo ora ritorni i dati veri
} catch (error) {
console.error('Errore:', error);
return []; // gestisci l'errore restituendo un default
}
}
```

Quando chiami `fetchData()` devi ancora attendere il risultato:
```javascript
fetchData().then(results => console.log(results));
```
Oppure in un'altra funzione async:
```javascript
async function main() {
const risultati = await fetchData();
console.log(risultati);
}
```

P.S. Hai presente quando prendi una fetta di ciambella ma ti accorgi che è vuota dentro? Ecco, è la stessa frustrazione di ritornare una promessa non risolta... 😅 La soluzione è aspettare TUTTE le promesse prima di manipolare i dati.
Avatar di gonzagacolombo50
Ah, jodycolombo60, ti capisco benissimo! Anche a me capitano questi intoppi che ti fanno battere la testa al muro. Mi è successo un sacco di volte di incartarmi con le Promise, è un classico!

Guarda, PippoSanna ha centrato il punto alla perfezione. Il problema sta proprio nel mix tra `await` e `.then()` che hai fatto. È come voler imparare l'inglese e lo spagnolo contemporaneamente, finisci per fare un minestrone e non parli bene nessuno dei due!

In pratica, quando hai scritto `const data = response.json().then(res => res.results);`, `data` non è il contenuto che ti aspetti, ma è *un'altra Promise* che deve ancora essere risolta. Il `then()` lì dentro non aspetta, e quindi la tua funzione restituisce la Promise non risolta.

La soluzione di PippoSanna è quella corretta: devi mettere `await` anche davanti a `response.json()`. Questo garantisce che il JSON venga parsato e che tu abbia il dato vero e proprio prima di passarlo avanti. E poi, ovviamente, quando chiami `fetchData()`, devi *sempre* aspettare il risultato con un `await` o un `.then()`, altrimenti ti ritrovi con la Promise in sospeso.

È un errore comune, non ti preoccupare. L'importante è imparare da queste "ciambelle vuote"! Io, per esempio, quando mi imbatto in queste cose, mi tuffo subito in qualche corso online, o magari rileggo un buon libro su JavaScript avanzato. C'è sempre qualcosa di nuovo da scoprire!
Avatar di andreabattaglia
@jodycolombo60 Ti è esplosa la Promise nello stesso modo in cui mi si rompe l'ikea Billy dopo due mesi! Il problema è che hai fatto un "all-in" misto tra await e .then() che genera un loop infinito di attese. Quando fai response.json().then(...), data diventa un'altra Promise non risolta, e la tua funzione ritorna quella instead dei dati. PippoSanna ha ragione: devi fare due await in cascata, come quando monti due ripiani consecutivi senza saltare i passaggi.

Un altro dettaglio che non vedo menzionato: quando chiami fetchData(), anche quella è una funzione async, quindi DEVI usare await o .then() quando la invochi. Se fai console.log(fetchData()) stai loggando la Promise, non il risultato.

Consiglio personale: io evito come la peste di mischiare .then() con async/await nello stesso blocco. Scelgo uno stile e lo mantengo, altrimenti è come cercare di usare il cacciavite a stella mentre leggi le istruzioni in svedese.

PS: Se l'API è lenta, prova ad aggiungere un timeout con Promise.race() per evitare loop infiniti. A me ha salvato la vita tipo ieri.
Avatar di jodycolombo60
@andreabattaglia Grazie per la spiegazione spara-dritto! La metafora dell'Ikea Billy mi ha ucciso 😂. Ora è chiarissimo: ho fatto un casino atomico mischiando await e .then(), e soprattutto non avevo realizzato che **fetchData() stessa ritorna una Promise** quando la chiamo senza await.
Farò come dici: butterò via quel .then() incriminato e userò **doppio await** pulito (response + response.json()). E prometto: o solo await o solo .then(), mai insieme.
Il trick di Promise.race() per i timeout è oro, proverò subito visto che l'API è più lenta di una lumaca sotto la neve.
Grazie mille, problema risolto!

La Tua Risposta

💬

Vuoi partecipare alla discussione?

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