Problema con await fetch

di il
9 risposte

Problema con await fetch

Salve.

Scusate, ma sto studiamo JS e non sono particolarmente ferrato sulle promises e affini. So che la domanda potrebbe risultare banale.

In ogni modo, o scritto questa funzione:

async function fetchText(id) {
  let response = await fetch('process.php',
    {
        method: 'post',
        headers: new Headers({
            'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
          }),
        body: `id=${id}`,
      });

  console.log(response.status); 
  console.log(response.statusText);
  if (response.status === 200) {
    let data = await response.text();
    // alert('Valore: ' + data);
    return data;
  }
}

Che richiamo con:

console.log(fetchText(idCaller));

Il file PHP è molto semplice, e tramite un echo restituisce un testo tramite una sequenza switch (correttamente, ho verificato).

Il mio problema è che quando richiamo la funzione con il console.log suddetto, mi si presenta l'errore di non completamento della promise cioè “Promise {<pending>}”.

Dov'è il problema?

9 Risposte

  • Re: Problema con await fetch

    In questo articolo hai una spiegazione, in particolare al capitolo 2 (Fetching JSON).

  • Re: Problema con await fetch

    Va bene.

    Ho modificato l'istruzione come segue:

        fetchText(idCaller + 5).then(data =>
          console.log(data));

    e, appunto, funziona.

    Quindi, la mia funzione non risolve la promise chiamata con async-await.

    E se io volessi risolverla internamente alla funzione, così da avere la stringa come return?

  • Re: Problema con await fetch

    05/10/2023 - BennyBatt ha scritto:


    Quindi, la mia funzione non risolve la promise chiamata con async-await.

    Sì, la tua funzione risolve la promise.

    Il problema qui è che la funzione fetch() restituisce una promise la quale, quando risolta, come valore di ritorno ti da di nuovo un'altra promise.

    Devi mettere await sulla chiamata a fetch(), e poi await sulla chiamata al metodo della response che ottieni per il dato convertito o interpretato nel formato desiderato (è uno degli esempi dell'articolo).

  • Re: Problema con await fetch

    Scusa, non voglio sempbrare impertinente, ma la mia funzione già prevede  per quanto riguarda la fetch:

     let response = await fetch(

    e sulla risposta:

    let data = await response.text();

    Probabilmente non capisco cosa intendi, e quindi non so come modificare la funzione.

  • Re: Problema con await fetch

    06/10/2023 - BennyBatt ha scritto:


    Probabilmente non capisco cosa intendi, e quindi non so come modificare la funzione.

    Pubblica il codice finale e completo, così possiamo analizzarlo nella sua interezza.

  • Re: Problema con await fetch

    Bene, riporto le 2 parti interessate, secondo quanto da me modificato a seghuito di quanto da te suggerito:

    Funzione: 

    async function fetchText(id) {
      let response = await fetch('process.php',
        {
            method: 'post',
            headers: new Headers({
                'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
              }),
            body: `id=${id}`,
          });
    
      console.log(response.status); 
      console.log(response.statusText); 
      if (response.status === 200) {
        let data = await response.text();
        // alert('Valore: ' + data);
        return data;
      }
    }

    E questa è la parte di codice che risolve la promise:

        fetchText(id_rif).then(function (data) {
          CustomBox.outerText = data;
          CustomBox.boxType = item.dataset.version;
          CustomBox.idCaller = i;
          if (item.hasAttribute('data-reference')) {
            CustomBox.reference = item.dataset.reference;
          }
          // inizializza l'oggetto
          CustomBox.init();
        });
        fetchText().catch(error => {
          error.message;
        });

    In questo modo funziona. Devo ancora sistemare la gestione degli errori.

    Pertò, mi piacerebbe che tutto fosse risolto nella funzione (se possibile).

  • Re: Problema con await fetch

    06/10/2023 - BennyBatt ha scritto:


    Pertò, mi piacerebbe che tutto fosse risolto nella funzione (se possibile).

    Non capisco cosa intendi. La tua funzione non può restituire la stringa bell'e pronta, perché è asincrona.

    Tu stesso hai scritto:

    async function fetchText(id)

    Quell'async davanti ha un significato: sta a indicare che, qualunque sia il valore di ritorno di quella funzione, verrà restituito in modalità asincrona, ossia recupererà in background il risultato e te lo restituirà quando esso sarà disponibile, senza bloccare l'esecuzione.

    Non esiste modo che tu possa creare una funzione che restituisca la stringa se, chiamando la funzione, questa darà luogo a operazioni in background che faranno avere una stringa solo al termine delle operazioni: ciò vuol dire lavorare in modo “bloccante”, ossia “sincrono”, perché per poter restituire una stringa dalla chiamata la funzione dovrà bloccare l'esecuzione fino a quando il dato non è disponibile, e ciò significa bloccare il programma.

    In sintesi, la tua funzione chiama operazioni asincrone, e pertanto sarà di fatto asincrona.

    Data questa premessa, hai due possibilità:

    1. se vuoi restituire un valore immediato nella funzione, questa non potrà essere altro che la Promise del risultato che arriverà al termine delle operazioni asincrone;
    2. se vuoi restituire direttamente la stringa, potrai farlo indicando però la funzione come async - così come hai fatto - ossia “la stringa la restituirò, ma tramite la Promise” quindi specificando il callback su then() (o usando await sulla chiamata alla funzione).

    Quello che chiedi di fare è un controsenso: a meno di non voler costruire qualcosa di “bloccante” e quindi assolutamente non consigliabile, non puoi far sì che la tua funzione restituisca precisamente una stringa, e subito, quando quella informazione proviene da operazioni asincrone che ti restituiranno quel dato solo dopo, più avanti (per definizione).

    Il tuo codice è corretto. Per poterlo essere completamente anche dal punto di vista di uniformità dello stile di codifica, basta modificarlo così:

    const data = await fetchText(id_rif);
    CustomBox.outerText = data;
    CustomBox.boxType = item.dataset.version;
    CustomBox.idCaller = i;
    if (item.hasAttribute('data-reference')) {
      CustomBox.reference = item.dataset.reference;
    }
    // inizializza l'oggetto
    CustomBox.init();
    // ...

    Pensaci su. :)

  • Re: Problema con await fetch

    Grazie della spiegazione, ora è più chiaro.

    E al tua proposta semplifica il codice.

    Solo una cosa: per “catturare” gli errori, seguendo la tua proposta. come devo modificare il .catch?:

  • Re: Problema con await fetch

    06/10/2023 - BennyBatt ha scritto:


    Solo una cosa: per “catturare” gli errori, seguendo la tua proposta. come devo modificare il .catch?:

    E' più semplice rispetto all'uso del catch() delle Promise: basta il costrutto try…catch “tradizionale”.

    Vedi gli esempi in questo articolo.

Devi accedere o registrarti per scrivere nel forum
9 risposte