<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Paolo Pescosolido - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Impara a programmare gratuitamente! Tutorial di programmazione su Python, JavaScript, Linux e molto altro. ]]>
        </description>
        <link>https://www.freecodecamp.org/italian/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Paolo Pescosolido - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/italian/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 18 May 2026 19:57:48 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/italian/news/author/paolo/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Tutorial JavaScript sulle Promise – Come Risolvere o Rifiutare le Promise in JS ]]>
                </title>
                <description>
                    <![CDATA[ Le Promise sono un concetto molto importante per le operazioni asincrone in JavaScript. Forse pensi che le promise non siano così facili da capire, apprendere e usare. E credimi non sei il solo! Le Promise sono impegnative per molti sviluppatori web, anche dopo anni passati a usarle. In questo articolo, ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-risolvere-o-rifiutare-le-promise-in-js/</link>
                <guid isPermaLink="false">640da9749896040622f6f8c5</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paolo Pescosolido ]]>
                </dc:creator>
                <pubDate>Thu, 23 Mar 2023 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/03/cover-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/javascript-promise-tutorial-how-to-resolve-or-reject-promises-in-js/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">JavaScript Promise Tutorial – How to Resolve or Reject Promises in JS</a>
      </p><p>Le <strong>Promise </strong>sono un concetto molto importante per le operazioni asincrone in JavaScript. Forse pensi che le promise non siano così facili da capire, apprendere e usare. E credimi non sei il solo!</p><p>Le Promise sono impegnative per molti sviluppatori web, anche dopo anni passati a usarle.</p><p>In questo articolo, cercherò di cambiare questa percezione e condividere quello che ho imparato sulle Promise in JavaScript negli ultimi anni. Spero che ti sia utile.</p><h1 id="cos-una-promise-in-javascript"><strong>Cos'è una P<strong>romise in JavaScript?</strong></strong></h1><p>Una <strong>Promise </strong>è un'oggetto speciale in JavaScript. Produce un valore quando un'operazione asincrona viene completata con successo, o un errore se non è completata con successo a causa di un &nbsp;timeout, un errore di rete, e via dicendo.</p><p>Una chiamata riuscita è indicata dalla chiamata della funzione <code>resolve</code>, mentre gli errori sono indicati dalla chiamata della funzione <code>reject</code>.</p><p>Puoi creare una promise usando il costruttore Promise in questo modo:</p><pre><code class="language-js">let promise = new Promise(function(resolve, reject) {    
    // Esegui delle operazioni asincrone, quindi chiama resolve o reject
});</code></pre><p>Nella maggior parte dei casi, una promise si usa per un'operazione asincrona. Tuttavia, tecnicamente, puoi risolvere/rifiutare sia operazioni sincrone che asincrone.</p><h1 id="aspetta-un-momento-non-abbiamo-gi-le-funzioni-callback-per-le-operazioni-asincrone"><strong>Aspetta un momento<strong>,</strong> non abbiamo già le funzioni callback per le operazioni asincrone<strong>?</strong></strong></h1><p>Esatto! In JavaScript esistono le funzioni <strong>callback</strong>. Ma, una callback non è niente di speciale. È una normale funzione che produce un risultato al completamento di un'operazione asincrona.</p><p>La parola 'asincrona' significa che una cosa succede nel futuro, non adesso. Normalmente, le callback si usano solamente per operazioni di rete, o caricare/scaricare file, consultare una base di dati, o cose del genere.</p><p>Nonostante le callback siano utili, hanno anche un grande svantaggio. In alcuni casi, possiamo avere una callback dentro un'altra callback dentro un'altra callback, e così via. Dico davvero! Cerchiamo di capire questo "inferno di callback" con un esempio.</p><h2 id="come-evitare-l-inferno-di-callback-esempio-con-pizzahub"><strong>Come evitare l'Inferno di c<strong>allback – </strong>Esempio con <strong>PizzaHub </strong></strong></h2><p>Ordiniamo una pizza Margherita Veg🍕 da PizzaHub. Quando facciamo un ordine, PizzaHub individua automaticamente la nostra posizione geografica, trova una pizzeria nei dintorni e controlla se la pizza che vogliamo è disponibile.</p><p>Se è disponibile individua che tipo di bibita possiamo avere gratis con la pizza, e finalmente invia l'ordine.</p><p>Se l'ordine va a buon fine, riceviamo un messaggio di conferma.</p><p>Quindi, come possiamo scrivere un codice per queste operazioni usando le funzioni callback? Io ho pensato a qualcosa del genere:</p><pre><code class="language-js">function orderPizza(type, name) {
    
    // Chiedi a pizzahub di trovare un ristorante
    query(`/api/pizzahub/`, function(result, error){
       if (!error) {
           let shopId = result.shopId;
           
           // Contatta il ristorante e chiedi le pizze
           query(`/api/pizzahub/pizza/${shopid}`, function(result, error){
               if (!error) {
                   let pizzas = result.pizzas;
                   
                   // Controlla se la pizza è dsponibile
                   let myPizza = pizzas.find((pizza) =&gt; {
                       return (pizza.type===type &amp;&amp; pizza.name===name);
                   });
                   
                   // Controlla le bibite gratis
                   query(`/api/pizzahub/beverages/${myPizza.id}`, function(result, error){
                       if (!error) {
                           let beverage = result.id;
                           
                           // Prepara l'ordine
                           query(`/api/order`, {'type': type, 'name': name, 'beverage': beverage}, function(result, error){
                              if (!error) {
                                  console.log(`Your order of ${type} ${name} with ${beverage} has been placed`);
                              } else {
                                  console.log(`Bad luck, No Pizza for you today!`);
                              }
                           });

                       }
                   })
               }
           });
       } 
    });
}

// Chiama il metodo orderPizza
orderPizza('veg', 'margherita');</code></pre><p>Esaminiamo meglio la funzione <code>orderPizza</code>.</p><p>Chiama una API per ottenere l'id del ristorante più vicino. Dopodiché, riceve la lista delle pizze disponibili nel ristorante. Controlla che la pizza che vogliamo è fra le disponibili e fa un'altra richiesta all'API per cercare le bibite da abbinare alla pizza. E infine invia l'ordine.</p><p>Qui stiamo usando una callback per ogni richiesta inviata all'API. Questo ci porta a dover usare una callback dentro un'altra callback, dentro un'altra callback, e così via.</p><p>Andiamo verso quello che chiamiamo (molto pittorescamente) inferno di callback. E penso che non piaccia a nessuno. Inoltre forma una piramide di codice che è fonte di confusione ma anche di possibili errori.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/11/callback-hell.png" class="kg-image" alt="callback-hell" width="600" height="400" loading="lazy"><figcaption>Dimostrazione dell'inferno di callback e della piramide</figcaption></figure><p>Ci sono vari modi per uscire dall'inferno di callback (o per non entrare). &nbsp;Il modo più comune è appunto quello di usare una <code>Promise</code> o una funzione <code>async</code>. Tuttavia, per capire bene cosa sia una funzione <code>async</code>, hai bisogno prima di avere una conoscenza sufficiente delle promise.</p><p>Quindi iniziamo e tuffiamoci nelle promise.</p><h1 id="comprendere-gli-stati-delle-promise"><strong>Comprendere gli stati delle <strong>Prom</strong>ise</strong></h1><p>Riassumendo, una promise può essere creata con la sintassi del costruttore (constructor), in questo modo:</p><pre><code class="language-js">let promise = new Promise(function(resolve, reject) {
  // Codice da eseguire
});</code></pre><p>Il costruttore ha come argomento una funzione. Quest'ultima funzione si chiama <strong>funzione esecutrice </strong>(executor).</p><pre><code class="language-js">// Funzione esecutrice passata come argomento
// al costruttore della promise
function(resolve, reject) {
    // la logica va qui...
}</code></pre><p>La funzione esecutrice accetta due argomenti, <code>resolve</code> e <code>reject</code>. Queste sono le callback fornite dal linguaggio JavaScript stesso. La logica del tuo programma va inserita nel corpo della funzione esecutrice che viene eseguita automaticamente quando una nuova promise è creata con la parola chiave <code>new</code>.</p><p>Per essere effettiva, la funzione executor della promise deve chiamare una delle due callback, <code>resolve</code> o <code>reject</code>. Entreremo nei dettagli più avanti.</p><p>La funzione constructor <code>new Promise()</code> restituisce un oggetto <code>promise</code>. Siccome la funzione executor gestisce operazioni asincrone, l'oggetto <code>promise</code> deve avere la capacità di informare quando l'esecuzione ha inizio, quando viene completata (resolved) o quando restituisce un errore (rejected).</p><p>Un oggetto <code>promise</code> possiede le seguenti proprietà interne:</p><ol><li><code>state</code> – Questa proprietà può avere i seguenti valori:</li></ol><ul><li><code>pending</code>: il valore iniziale quando inizia l'esecuzione della funzione esecutrice (in sospeso).</li><li><code>fulfilled</code>: quando la promise è risolta.</li><li><code>rejected</code>: quando la promise è rifiutata.</li></ul><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/11/states_1.png" class="kg-image" alt="states_1" width="600" height="400" loading="lazy"><figcaption>Stati di una promise</figcaption></figure><p>2. &nbsp;<code>result</code> – Questa proprietà può avere i seguenti valori:</p><ul><li><code>undefined</code>: il valore iniziale quando la proprietà <code>state</code> ha valore <code>pending</code>.</li><li><code>valore</code>: quando viene chiamata <code>resolve(valore)</code>.</li><li><code>errore</code>: quando viene chiamata <code>reject(errore)</code>.</li></ul><p>Queste proprietà interne, sono inaccessibili da un codice esterno, ma sono ispezionabili. Ovvero possiamo ispezionare il valore delle proprietà <code>state</code> e <code>result</code> con gli strumenti di debug, ma non possiamo accedervi direttamente tramite il programma.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/11/promise_state_inspect.png" class="kg-image" alt="promise_state_inspect" width="600" height="400" loading="lazy"><figcaption>Possiamo ispezionare le proprietà interne di una promise</figcaption></figure><p>Lo stato di una promise può essere <code>pending</code> (sospesa), <code>fulfilled</code> (soddisfatta) o <code>rejected</code> (respinta, rifiutata). Una promise risolta o rifiutata viene chiamata <code>settled</code> (conclusa).</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/11/states_2.png" class="kg-image" alt="states_2" width="600" height="400" loading="lazy"><figcaption>Una promise conclusa può essere sia soddisfatta che rifiutata</figcaption></figure><h3 id="come-si-risolve-o-si-rifiuta-una-promise"><strong>Come si risolve o si rifiuta una promise</strong></h3><p>Ecco un esempio di una promise risolta (stato <code>fulfilled</code>) immediatamente con il valore <code>I am done</code>.</p><pre><code class="language-js">let promise = new Promise(function(resolve, reject) {
    resolve("I am done");
});</code></pre><p>La seguente promise è rifiutata (stato <code>rejected</code>) con il messaggio di errore <code>Something is not right!</code>.</p><pre><code class="language-js">let promise = new Promise(function(resolve, reject) {
    reject(new Error('Something is not right!'));
});</code></pre><p>Una cosa importante da notare:</p><blockquote>La funzione executor di una Promise deve chiamare solo una volta <code>resolve</code> o <code>reject</code>. Una volta che lo stato passa da pending a fulfilled o da pending a rejected, è tutto. Qualsiasi ulteriore chiamata di <code>resolve</code> o <code>reject</code> viene ignorata.</blockquote><pre><code class="language-js">let promise = new Promise(function(resolve, reject) {
  resolve("I am surely going to get resolved!");

  reject(new Error('Will this be ignored?')); // ignorato
  resolve("Ignored?"); // ignorato
});</code></pre><p>Nell'esempio precedente, solo la prima chiamata di resolve avviene, mentre il resto viene ignorato.</p><h1 id="come-gestire-una-promise-una-volta-creata"><strong>Come gestire una Promise una volta creata</strong></h1><p>Una <code>Promise</code> utilizza una funzione executor per completare un'operazione (di solito asincrona). Una funzione che usa il risultato di una promise, dovrebbe essere avvertita quando la funzione executor ha terminato il suo lavoro chiamando resolve o reject.</p><p>I metodi <code>.then()</code>, <code>.catch()</code> e <code>.finally()</code>, servono per creare questo collegamento fra la funzione executor e la funzione che consuma la promise (consumer), in modo tale che possano essere sincronizzate quando la promise è risolta o rifiutata.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/11/consumer_executor.png" class="kg-image" alt="consumer_executor" width="600" height="400" loading="lazy"><figcaption>La funzione executor e la funzione consumer che usa il risultato della promise</figcaption></figure><h2 id="come-usare-il-metodo-then-"><strong>Come usare il metodo <strong><code>.then()</code></strong></strong></h2><p>Il metodo <code>.then()</code> dovrebbe essere chiamato sull'oggetto promise per gestire un risultato (resolve) o un errore (reject).</p><p>Il metodo accetta due funzioni come parametri. Normalmente, il metodo <code>.then()</code> viene chiamato dalla funzione consumer quando vuoi conoscere il risultato dell'esecuzione di una promise.</p><pre><code class="language-js">promise.then(
  (result) =&gt; { 
     console.log(result);
  },
  (error) =&gt; { 
     console.log(error);
  }
);</code></pre><p>Se ti interessa solo il risultato in caso di successo, puoi passare un solo argomento, in questo modo:</p><pre><code class="language-js">promise.then(
  (result) =&gt; { 
      console.log(result);
  }
);</code></pre><p>Se ti interessa solo il risultato in caso di errore, puoi passare <code>null</code> come primo argomento, in questo modo:</p><pre><code class="language-js">promise.then(
  null,
  (error) =&gt; { 
      console.log(error)
  }
);</code></pre><p>In ogni caso, puoi gestire meglio gli errori usando il metodo <code>.catch()</code> che vedremo in un minuto.</p><p>Vediamo un paio di esempi di come gestire i risultati e gli errori usando i metodi <code>.then</code> e <code>.catch</code>. Vediamo di rendere le cose un po' più divertenti con delle richieste asincrone reali. Useremo la <a href="https://pokeapi.co/">PokeAPI</a> per richiedere informazioni sui Pokémon e gestire i risultati con le promise e le funzioni resolve/reject.</p><p>Per prima cosa, creiamo una funzione generica che accetta un URL della PokeAPI come argomento e ritorna una promise. Se la richiesta alla API ha successo, restituiremo una promise risolta (resolved). In caso di errore, restituiremo una promise rifiutata (rejected).</p><p>D'ora in poi useremo questa funzione in vari esempi per ottenere una promise e lavorare con essa.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">function getPromise(URL) {
  let promise = new Promise(function (resolve, reject) {
    let req = new XMLHttpRequest();
    req.open("GET", URL);
    req.onload = function () {
      if (req.status == 200) {
        resolve(req.response);
      } else {
        reject("There is an Error!");
      }
    };
    req.send();
  });
  return promise;
}</code></pre><figcaption>Metodo di utilità per ottenere una Promise</figcaption></figure><p>Esempio 1: ottieni informazioni su 50 Pokémon:</p><pre><code class="language-js">const ALL_POKEMONS_URL = 'https://pokeapi.co/api/v2/pokemon?limit=50';

// Abbiamo già parlato di questa funzione!
let promise = getPromise(ALL_POKEMONS_URL);

const consumer = () =&gt; {
    promise.then(
        (result) =&gt; {
            console.log({result}); // Registra il risultato di 50 Pokemons
        },
        (error) =&gt; {
            // Visto che l'URL è valido, questa funzione non sarà chiamata.
            console.log('We have encountered an Error!'); // Registra un errore
    });
}

consumer();</code></pre><p>Esempio 2: proviamo con URL non valido</p><pre><code class="language-js">const POKEMONS_BAD_URL = 'https://pokeapi.co/api/v2/pokemon-bad/';

// Questa promise sarà rifiutata perché l'URL è 404
let promise = getPromise(POKEMONS_BAD_URL);

const consumer = () =&gt; {
    promise.then(
        (result) =&gt; {
            // La promise non è risolta. Quindi, questa funzione
            // non sarà eseguita.
            console.log({result});
        },
        (error) =&gt; {
            // Una promise rifiutata eseguirà questa funzione
            console.log('We have encountered an Error!'); // Registra un errore
        }
    );
}

consumer();</code></pre><h2 id="come-usare-il-metodo-catch-"><strong>Come usare il metodo <strong><code>.catch()</code></strong></strong></h2><p>Puoi usare questo metodo per gestire gli errori in una promise. La sintassi di passare <code>null</code> come primo argomento di <code>.then()</code> non è esattamente un gran modo di gestire gli errori. Per questo abbiamo <code>.catch()</code> per eseguire lo stesso lavoro con una sintassi più pulita:</p><pre><code class="language-js">// Questa promise sarà rifiutata perché l'URL è 404
let promise = getPromise(POKEMONS_BAD_URL);

const consumer = () =&gt; {
    promise.catch(error =&gt; console.log(error));
}

consumer();</code></pre><p>Se lanciamo un errore come <code>new Error("Something wrong!")</code> invece di chiamare <code>reject</code> dalla funzione executor, sarà considerato comunque un rifiuto. Ovvero l'errore sarà intercettato dal metodo <code>.catch</code>.</p><p>Lo stesso succede per ogni eccezione <em><em>s</em>incrona </em>che avviene nella funzione executor o in una funzione di gestione.</p><p>Questo è un esempio in cui un errore viene trattato come un rifiuto e il metodo <code>.catch</code> viene chiamato:</p><pre><code class="language-js">new Promise((resolve, reject) =&gt; {
  throw new Error("Something is wrong!");// nessuna chiamata di reject
}).catch((error) =&gt; console.log(error)); </code></pre><h2 id="come-usare-il-metodo-finally-"><strong>Come usare il metodo <strong><code>.finally()</code></strong></strong></h2><p>Il metodo <code>.finally()</code> svolge operazioni di pulizia come interrompere un caricamento, chiudere una connessione attiva, e così via. Il metodo <code>finally()</code> viene chiamato a prescindere del fatto che una promise sia risolta o rifiutata. Passa il risultato o l'errore al gestore seguente, che a sua volta potrà chiamare <code>.then()</code> o <code>.catch()</code>.</p><p>Questo è un esempio che ti aiuterà a capire i tre metodi insieme:</p><pre><code class="language-js">let loading = true;
loading &amp;&amp; console.log('Loading...');

// Ottieni la promise
promise = getPromise(ALL_POKEMONS_URL);

promise.finally(() =&gt; {
    loading = false;
    console.log(`Promise Settled and loading is ${loading}`);
}).then((result) =&gt; {
    console.log({result});
}).catch((error) =&gt; {
    console.log(error)
});</code></pre><p>Per spiegare meglio:</p><ul><li>Il metodo <code>.finally()</code> cambia il valore di <code>loading</code> in <code>false</code>.</li><li>Se la promise è risolta, il metodo <code>.then()</code> viene chiamato. Se la promise è rifiutata con un errore, viene chiamato il metodo <code>.catch()</code>. Il metodo <code>.finally()</code> sarà chiamato comunque a prescindere che la promise sia risolta o rifiutata.</li></ul><h1 id="cos-la-catena-di-promise"><strong>Cos'è la catena di Promise<strong>?</strong></strong></h1><p>La chiamata <code>promise.then()</code> restituisce sempre una promise. Questa promise avrà la proprietà <code>state</code> con valore <code>pending</code> e <code>result</code> sarà <code>undefined</code>. Ci permette chiamare il metodo <code>.then</code> sulla nuova promise.</p><p>Quando il primo <code>.then</code> restituisce un valore, il seguente <code>.then</code> può ricevere questo valore. Il secondo <code>.then</code> &nbsp;può passarlo al terzo e così via. Tutto questo forma una catena di <code>.then</code> che trasmette le promise. Questo fenomeno viene chiamato <strong>promise chain</strong> (catena di promise).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-105.png" class="kg-image" alt="image-105" width="600" height="400" loading="lazy"><figcaption>Promise Chain</figcaption></figure><p>Ecco un esempio:</p><pre><code class="language-js">let promise = getPromise(ALL_POKEMONS_URL);

promise.then(result =&gt; {
    let onePokemon = JSON.parse(result).results[0].url;
    return onePokemon;
}).then(onePokemonURL =&gt; {
    console.log(onePokemonURL);
}).catch(error =&gt; {
    console.log('In the catch', error);
});</code></pre><p>Qui per prima cosa otteniamo una promise risolta e quindi estraiamo l'URL per raggiungere il primo Pokémon. Quindi restituiamo questo valore che viene passato come promise al seguente metodo .then(). E dunque il risultato:</p><pre><code class="language-shell">https://pokeapi.co/api/v2/pokemon/1/</code></pre><p>Il metodo <code>.then</code> può restituire:</p><ul><li>Un valore (già abbiamo visto questo caso)</li><li>Oppure una nuova promise.</li></ul><p>Inoltre può anche dare un errore.</p><p>Ecco un esempio in cui creiamo una catena di promise con vari metodi <code>.then</code> che restituiscono dei risultati e una nuova promise:</p><pre><code class="language-js">// Catena di promise con then e catch multipli
let promise = getPromise(ALL_POKEMONS_URL);

promise.then(result =&gt; {
    let onePokemon = JSON.parse(result).results[0].url;
    return onePokemon;
}).then(onePokemonURL =&gt; {
    console.log(onePokemonURL);
    return getPromise(onePokemonURL);
}).then(pokemon =&gt; {
    console.log(JSON.parse(pokemon));
}).catch(error =&gt; {
    console.log('In the catch', error);
});</code></pre><p>Nel primo <code>.then</code> estraiamo l'URL e restituiamo il suo valore. Questo URL viene passato al secondo <code>.then</code> che restituisce una nuova promise che prende l'URL come argomento.</p><p>Quest'ultima promise viene risolta e trasmessa nella catena dove otteniamo le informazioni sul Pokémon. Questo è il risultato:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-159.png" class="kg-image" alt="image-159" width="600" height="400" loading="lazy"><figcaption>Output della catena di promise</figcaption></figure><p>Nel caso in cui ci fosse un errore o una promise rifiutata, il metodo .catch nella catena verrebbe chiamato.</p><p>Un punto importante: chiamare <code>.then</code> più volte non forma una catena di promise. Potresti finire per introdurre un bug nel codice:</p><pre><code class="language-js">let promise = getPromise(ALL_POKEMONS_URL);

promise.then(result =&gt; {
    let onePokemon = JSON.parse(result).results[0].url;
    return onePokemon;
});
promise.then(onePokemonURL =&gt; {
    console.log(onePokemonURL);
    return getPromise(onePokemonURL);
});
promise.then(pokemon =&gt; {
    console.log(JSON.parse(pokemon));
});
</code></pre><p>Abbiamo chiamato il metodo <code>.then</code> tre volte sulla stessa promise, ma non abbiamo trasmesso la promise. Questo è diverso dalla catena di promise. Nell'ultimo esempio, Il risultato sarebbe un errore.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-160.png" class="kg-image" alt="image-160" width="600" height="400" loading="lazy"></figure><h1 id="come-gestire-promise-multiple"><strong>Come gestire promise multiple</strong></h1><p>Oltre ai gestori (.then, .catch e .finally), esistono sei metodi statici disponibili nella API Promise. I primi quattro metodi accettano un array di promise e le eseguono in parallelo.</p><ol><li>Promise.all</li><li>Promise.any</li><li>Promise.allSettled</li><li>Promise.race</li><li>Promise.resolve</li><li>Promise.reject</li></ol><p>Vediamoli uno a uno.</p><h2 id="il-metodo-promise-all-"><strong>Il metodo <strong>Promise.all()</strong></strong></h2><p><code>Promise.all([promise])</code> accetta una collezione (per esempio, un array) di promise come argomento e le esegue in parallelo.</p><p>Questo metodo aspetta fino a che tutte le promise siano risolte e ritorna un array con i loro risultati. Se una qualsiasi di queste promise viene rifiutata o non viene eseguita a causa di un errore, i risultati di tutte le altre vengono ignorati.</p><p>Creiamo tre promise per ottenere informazioni su tre Pokémon.</p><pre><code class="language-js">const BULBASAUR_POKEMONS_URL = 'https://pokeapi.co/api/v2/pokemon/bulbasaur';
const RATICATE_POKEMONS_URL = 'https://pokeapi.co/api/v2/pokemon/raticate';
const KAKUNA_POKEMONS_URL = 'https://pokeapi.co/api/v2/pokemon/kakuna';


let promise_1 = getPromise(BULBASAUR_POKEMONS_URL);
let promise_2 = getPromise(RATICATE_POKEMONS_URL);
let promise_3 = getPromise(KAKUNA_POKEMONS_URL);</code></pre><p>E usiamo il metodo Promise.all() passando un array di promise.</p><pre><code class="language-js">Promise.all([promise_1, promise_2, promise_3]).then(result =&gt; {
    console.log({result});
}).catch(error =&gt; {
    console.log('An Error Occured');
});</code></pre><p>Risultato:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-161.png" class="kg-image" alt="image-161" width="600" height="400" loading="lazy"></figure><p>Come puoi vedere, viene restituito il risultato di tutte le promise. Il tempo di esecuzione di tutte le promise è uguale al tempo massimo di esecuzione della promise più "lenta".</p><h2 id="il-metodo-promise-any-"><strong>Il metodo<strong> Promise.any()</strong></strong></h2><p><code>Promise.any([promise])</code> - Simile al metodo <code>all()</code>, anche <code>.any()</code> accetta un array di promise da eseguire in parallelo. Però questo metodo non aspetta che tutte le promise siano risolte. Termina quando una qualsiasi delle promise è conclusa.</p><pre><code class="language-javascript"> Promise.any([promise_1, promise_2, promise_3]).then(result =&gt; {
     console.log(JSON.parse(result));
 }).catch(error =&gt; {
     console.log('An Error Occured');
 });</code></pre><p>Il risultato sarà il risultato di una delle promise risolte:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-162.png" class="kg-image" alt="image-162" width="600" height="400" loading="lazy"></figure><h2 id="il-metodo-promise-allsettled-"><strong>Il metodo<strong> Promise.allSettled()</strong></strong></h2><p><code>Promise.allSettled([promise])</code> - Questo metodo aspetta che tutte le promise siano concluse (risolte o rifiutate) e ritorna i loro risultati come un array di oggetti. I risultati conterranno la stato (fulfilled/rejected) e il valore, se lo stato è fulfilled. Nel caso in cui lo stato sia rejected, ritornerà la ragione dell'errore.</p><p>Ecco un esempio di tutte promise con stato fulfilled:</p><pre><code class="language-js">Promise.allSettled([promise_1, promise_2, promise_3]).then(result =&gt; {
    console.log({result});
}).catch(error =&gt; {
    console.log('There is an Error!');
});</code></pre><p>Risultato:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-163.png" class="kg-image" alt="image-163" width="600" height="400" loading="lazy"></figure><p>Se qualcuna delle promise fosse rifiutata, per esempio la promise_1,</p><pre><code class="language-javascript">let promise_1 = getPromise(POKEMONS_BAD_URL);</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-164.png" class="kg-image" alt="image-164" width="600" height="400" loading="lazy"></figure><h2 id="il-metodo-promise-race-"><strong>Il<strong> </strong>metodo <strong>Promise.race()</strong></strong></h2><p><code>Promise.race([promises])</code> – Aspetta la prima promise (la più veloce) a essere conclusa, e ritorna il risultato/errore di conseguenza.</p><pre><code class="language-js">Promise.race([promise_1, promise_2, promise_3]).then(result =&gt; {
    console.log(JSON.parse(result));
}).catch(error =&gt; {
    console.log('An Error Occured');
});</code></pre><p>Il risultato sarà la promise che viene risolta più rapidamente:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-165.png" class="kg-image" alt="image-165" width="600" height="400" loading="lazy"></figure><h2 id="i-metodi-promise-resolve-reject"><strong>I metodi<strong> Promise.resolve/reject</strong></strong></h2><p><code>Promise.resolve(value)</code> – Risolve una promise con il valore passato come argomento. È equivalente al seguente codice:</p><pre><code class="language-js">let promise = new Promise(resolve =&gt; resolve(value));</code></pre><p><code>Promise.reject(error)</code> – Rifiuta una promise con l'errore passato come argomento. È equivalente al seguente codice:</p><pre><code class="language-js">let promise = new Promise((resolve, reject) =&gt; reject(error));</code></pre><h1 id="possiamo-riscrivere-l-esempio-di-pizzahub-con-le-promise"><strong>Possiamo riscrivere l'esempio di <strong>PizzaHub </strong>con le </strong>promise<strong><strong>?</strong></strong></h1><p>Certo che sì, facciamolo. Supponiamo che il metodo <code>query</code> ritorni una promise. Nella vita reale, questo metodo potrebbe comunicare con un database e restituire i risultati. In questo caso, restituisce un risultato predeterminato, ma va bene per il nostro esempio.</p><pre><code class="language-js">function query(endpoint) {
  if (endpoint === `/api/pizzahub/`) {
    return new Promise((resolve, reject) =&gt; {
      resolve({'shopId': '123'});
    })
  } else if (endpoint.indexOf('/api/pizzahub/pizza/') &gt;=0) {
    return new Promise((resolve, reject) =&gt; {
      resolve({pizzas: [{'type': 'veg', 'name': 'margherita', 'id': '123'}]});
    })
  } else if (endpoint.indexOf('/api/pizzahub/beverages') &gt;=0) {
    return new Promise((resolve, reject) =&gt; {
      resolve({id: '10', 'type': 'veg', 'name': 'margherita', 'beverage': 'coke'});
    })
  } else if (endpoint === `/api/order`) {
    return new Promise((resolve, reject) =&gt; {
      resolve({'type': 'veg', 'name': 'margherita', 'beverage': 'coke'});
    })
  }
}</code></pre><p>Il prossimo passo è il refactoring del nostro inferno di callback. A questo scopo, per prima cosa, creeremo alcune funzioni logiche:</p><pre><code class="language-js">// Restituisce shop id
let getShopId = result =&gt; result.shopId;

// Restituisce una promise con la liste delle pizze del ristorante
let getPizzaList = shopId =&gt; {
  const url = `/api/pizzahub/pizza/${shopId}`;
  return query(url);
}

// Restituisce una promise con la pizza che corrisponde alle richieste del cliente
let getMyPizza = (result, type, name) =&gt; {
  let pizzas = result.pizzas;
  let myPizza = pizzas.find((pizza) =&gt; {
    return (pizza.type===type &amp;&amp; pizza.name===name);
  });
  const url = `/api/pizzahub/beverages/${myPizza.id}`;
  return query(url);
}

// Restituisce una promise dopo aver ordinato
let performOrder = result =&gt; {
  let beverage = result.id;
   return query(`/api/order`, {'type': result.type, 'name': result.name, 'beverage': result.beverage});
}

// Conferma l'ordine
let confirmOrder = result =&gt; {
    console.log(`Your order of ${result.type} ${result.name} with ${result.beverage} has been placed!`);
}</code></pre><p>Usiamo queste funzioni per creare le promise necessarie. Questo è il codice che dovresti paragonare con l'esempio dell'inferno di callback. È molto più bello ed elegante.</p><pre><code class="language-js">function orderPizza(type, name) {
  query(`/api/pizzahub/`)
  .then(result =&gt; getShopId(result))
  .then(shopId =&gt; getPizzaList(shopId))
  .then(result =&gt; getMyPizza(result, type, name))
  .then(result =&gt; performOrder(result))
  .then(result =&gt; confirmOrder(result))
  .catch(function(error){
    console.log(`Bad luck, No Pizza for you today!`);
  })
}</code></pre><p>E infine, chiamiamo il metodo orderPizza() passando il tipo e il nome della pizza, in questo modo:</p><pre><code class="language-js">orderPizza('veg', 'margherita');
</code></pre><h1 id="cosa-viene-dopo"><strong>Cosa viene dopo<strong>?</strong></strong></h1><p>Se sei arrivato fin qui e hai letto la maggior parte di questo articolo, congratulazioni! Dovresti avere un'idea più chiara sulle promise in JavaScript. Puoi trovare tutti gli esempi usati nell'articolo in questo <a href="https://github.com/atapas/js-promise-example">repository GitHub</a>.</p><p>Il prossimo passo, dovrebbe essere apprendere le funzioni <code>async</code> in JavaScript che semplificano ulteriormente le cose. Il concetto delle promise in JavaScript si apprende meglio scrivendo dei piccoli esempi e lavorando su di essi.</p><p>A prescindere dal framework o dalla libreria che usiamo (Angular, React, Vue, ecc.), le operazioni asincrone sono inevitabili. Questo vuol dire che dobbiamo capire le promise per lavorare meglio.</p><p>Inoltre, sono sicuro che l'uso del metodo <code>fetch</code> ti risulterà più facile adesso:</p><pre><code class="language-js">fetch('/api/user.json')
.then(function(response) {
    return response.json();
})
.then(function(json) {
    console.log(json); // {"name": "tapas", "blog": "freeCodeCamp"}
});</code></pre><ul><li>Il metodo <code>fetch</code> restituisce una promise. Quindi possiamo usare il metodo <code>.then</code>.</li><li>Il resto riguarda la catena di promise che abbiamo imparato in questo articolo.</li></ul><h1 id="prima-di-terminare-"><strong>Prima di terminare<strong>...</strong></strong></h1><p>Grazie per aver letto fin qui! Connettiamoci. Puoi taggarmi su <a href="https://twitter.com/tapasadhikary">Twitter (@tapasadhikary)</a> in un commento.</p><p>Potresti trovare interessanti anche questi articoli:</p><ul><li><a href="https://blog.greenroots.info/javascript-undefined-and-null-lets-talk-about-it-one-last-time-ckh64kmz807v848s15kdkg3dd">JavaScript undefined and null: Let's talk about it one last time!</a></li><li><a href="https://blog.greenroots.info/javascript-equality-comparison-with-and-objectis-ckdpt2ryk01vel9s186ft8cwl">JavaScript: Equality comparison with ==, === and Object.is</a></li><li><a href="https://www.freecodecamp.org/news/javascript-this-keyword-binding-rules/">The JavaScript `this` Keyword + 5 Key Binding Rules Explained for JS Beginners</a></li><li><a href="https://www.freecodecamp.org/news/javascript-typeof-how-to-check-the-type-of-a-variable-or-object-in-js/">JavaScript TypeOf – How to Check the Type of a Variable or Object in JS</a></li></ul><p>È tutto per adesso. Ci vediamo presto con il mio prossimo articolo. Stammi bene.</p><hr> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Ambito di Visibilità e Chiusure in JavaScript – Spiegate con Esempi ]]>
                </title>
                <description>
                    <![CDATA[ Potresti aver visto o aver scritto alcune volte del codice come questo in JavaScript: function sayWord(word) { 	return () => console.log(word); } const sayHello = sayWord("hello"); sayHello(); // "hello" Questo codice è interessante per un paio di motivi. Primo, possiamo accedere a  word nella funzione restituita da sayWord. Secondo, ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/ambito-di-visibilita-e-chiusure-in-javascript/</link>
                <guid isPermaLink="false">63e8c0dc87f2e0059ba2c96d</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paolo Pescosolido ]]>
                </dc:creator>
                <pubDate>Wed, 22 Feb 2023 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/02/karine-avetisyan-ipuiM-36tAg-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/scope-and-closures-in-javascript/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Scope and Closures in JavaScript – Explained with Examples</a>
      </p><p>Potresti aver visto o aver scritto alcune volte del codice come questo in JavaScript:</p><pre><code class="language-javascript">function sayWord(word) {
	return () =&gt; console.log(word);
}

const sayHello = sayWord("hello");

sayHello(); // "hello"</code></pre><p>Questo codice è interessante per un paio di motivi. Primo, possiamo accedere a <code>word</code> nella funzione restituita da <code>sayWord</code>. Secondo, possiamo accedere al valore di <code>word</code> quando chiamiamo <code>sayHello</code> – anche se chiamiamo <code>sayHello</code> da dove normalmente non avremmo accesso a <code>word</code>.</p><p>In questo articolo, apprenderemo cosa sono lo scope (ambito di visibilità) e le closure (chiusure), che consentono questo tipo di comportamento.</p><h2 id="introduzione-all-ambito-di-visibilit-in-javascript"><strong>Introduzione all'Ambito di Visibilità in JavaScript</strong></h2><p>L'ambito di visibilità è il primo pezzo che ci aiuterà a comprendere l'esempio precedente. L'ambito di visibilità di una variabile è la parte di un programma in cui la variabile è accessibile.</p><p>Le variabili in JavaScript hanno un ambito di visibilità lessicale, ossia possiamo determinare l'ambito di visibilità di una variabile in base a dove è dichiarata nel codice (ciò non è del tutto esatto: le variabili dichiarate con <code>var</code> non hanno un ambito di visibilità lessicale, ma ne riparleremo a breve).</p><p>Per esempio:</p><pre><code class="language-javascript">if (true) {
	const foo = "foo";
	console.log(foo); // "foo"
}</code></pre><p>L'istruzione <code>if</code> introduce un ambito di blocco tramite una <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block">dichiarazione di blocco</a>. Diciamo che <code>foo</code> ha un "ambito di visibilità di blocco" relativo all'istruzione <code>if</code>. Ciò significa che è accessibile solo dal codice dentro il blocco <code>if</code>.</p><p>Se provassimo ad accedere alla variabile <code>foo</code> dall'esterno di questo blocco, otterremmo un <code>ReferenceError</code> perché la variabile è fuori dall'attuale ambito di visibilità:</p><pre><code class="language-javascript">if (true) {
	const foo = "foo";
	console.log(foo); // "foo"
}

console.log(foo); // Uncaught ReferenceError: foo is not defined</code></pre><p>Anche le altre istruzioni di blocco, come i loop <code>for</code> e <code>while</code>, creano un ambito di visibilità di blocco per le variabili. Per esempio, <code>foo</code> ha un ambito di visibilità limitato al corpo della funzione di seguito:</p><pre><code class="language-javascript">function sayFoo() {
	const foo = "foo";
	console.log(foo);
}

sayFoo(); // "foo"

console.log(foo); // Uncaught ReferenceError: foo is not defined</code></pre><h2 id="ambito-di-visibilit-annidato-e-funzioni"><strong>Ambito di V</strong>isibilità A<strong>nnidato e Funzioni</strong></h2><p>JavaScript permette blocchi annidati e di conseguenza ambiti di visibilità annidati. Questi ultimi creano un albero o catena di ambiti di visibilità.</p><p>Consideriamo il seguente codice, che annida molteplici istruzioni di blocco:</p><pre><code class="language-javascript">if (true) {
	const foo = "foo";
	console.log(foo); // "foo"

	if (true) {
		const bar = "bar";
		console.log(foo); // "foo"

		if (true) {
			console.log(foo, bar); // "foo bar"
		}
	}
}</code></pre><p>JavaScript ci permette anche di annidare le funzioni:</p><pre><code class="language-javascript">function foo(bar) {
	function baz() {
		console.log(bar);
	}

	baz();
}

foo("bar"); // "bar"</code></pre><p>Come previsto, possiamo accedere alle variabili dall'ambito di visibilità in cui sono state dichiarate. Ma possiamo anche accedere alle variabili dall'ambito di visibilità interno (l'ambito di visibilità creato all'interno dell'ambito di visibilità della variabile stessa). Ovvero possiamo accedere a una variabile dall'ambito di visibilità in cui è stata dichiarata e da ogni ambito interno ad esso.</p><p>Prima di andare avanti è meglio chiarire come varia questo meccanismo in base a come dichiariamo una variabile.</p><h2 id="ambito-di-visibilit-di-let-const-e-var-in-javascript"><strong>Ambito di </strong>visibilità <strong>di let, const e var in JavaScript</strong></h2><p>Possiamo creare una variabile con una dichiarazione <code>let</code>, <code>const</code> e <code>var</code>. Per <code>let</code> e <code>const</code>, l'ambito di visibilità di blocco funziona come abbiamo appena spiegato. Mentre <code>var</code> funziona in maniera differente.</p><h3 id="let-e-const"><strong>let e const</strong></h3><p><code>let</code> e <code>const</code> creano variabili con ambito di blocco. Quando sono dichiarate all'interno di un blocco, sono accessibili solo dall'interno di quel blocco. Questo comportamento è stato mostrato nell'esempio precedente:</p><pre><code class="language-javascript">if (true) {
	const foo = "foo";
	console.log(foo); // "foo"
}

console.log(foo); // Uncaught ReferenceError: foo is not defined</code></pre><h3 id="var"><strong>var</strong></h3><p>L'ambito di visibilità di variabili create con <code>var</code> corrisponde al più vicino ambito di funzione o all'ambito globale (che discuteremo fra breve). Non hanno un ambito di visibilità di blocco:</p><pre><code class="language-javascript">function foo() {
	if (true) {
		var foo = "foo";
	}
	console.log(foo);
}

foo(); // "foo"</code></pre><p><code>var</code> può creare situazioni confuse, e la includo in questo articolo solo per completezza. Quando è possibile è meglio usare <code>let</code> e <code>const</code>. Per il resto dell'articolo useremo solo variabili dichiarate con <code>let</code> e <code>const</code>.</p><p>Se sei interessato a come funziona esattamente <code>var</code> nell'esempio precedente, puoi trovare maggiori informazioni nel <a href="https://www.freecodecamp.org/italian/news/cose-lhoisting-in-javascript/">mio articolo sull'hoisting</a>.</p><h2 id="ambito-di-visibilit-globale-e-di-modulo-in-javascript"><strong>Ambito di visibilità Globale e di Modulo in JavaScript</strong></h2><p>Oltre all'ambito di blocco, le variabili possono avere anche un ambito di visibilità globale o di modulo.</p><p>In un browser, l'ambito globale è il livello più alto dello script. È la radice dell'albero di cui abbiamo parlato prima. Quindi, creare una variabile nell'ambito globale la rende accessibile da qualsiasi altro ambito:</p><pre><code class="language-html">&lt;script&gt;
	const foo = "foo";
&lt;/script&gt;
&lt;script&gt;
	console.log(foo); // "foo"
		
	function bar() {
		if (true) {
			console.log(foo);
		}
	}

	bar(); // "foo"
&lt;/script&gt;</code></pre><p>Ogni modulo invece ha il proprio ambito di visibilità. Le variabili dichiarate in un modulo sono accessibili solo da dentro quel modulo - non sono globali:</p><pre><code class="language-html">&lt;script type="module"&gt;
	const foo = "foo";
&lt;/script&gt;
&lt;script&gt;
	console.log(foo); // Uncaught ReferenceError: foo is not defined
&lt;/script&gt;</code></pre><h2 id="chiusure-in-javascript"><strong>Chiusure in JavaScript</strong></h2><p>Adesso che abbiamo capito come funziona l'ambito di visibilità, possiamo tornare all'esempio che abbiamo visto nell'introduzione:</p><pre><code class="language-javascript">function sayWord(word) {
	return () =&gt; console.log(word);
}

const sayHello = sayWord("hello");

sayHello(); // "hello"</code></pre><p>Ricorda che c'erano due cose interessanti in questo esempio:</p><ol><li>La funzione restituita da <code>sayWord</code> ha accesso al parametro <code>word</code> </li><li>La funzione restituita mantiene il valore di <code>word</code> quando <code>sayHello</code> è chiamata fuori dall'ambito di visibilità di <code>word</code></li></ol><p>Il primo punto può essere spiegato dall'ambito lessicale: la funzione ritornata può accedere a <code>word</code> perché esiste nel suo ambito esterno.</p><p>Il secondo punto si spiega con le chiusure: una chiusura è una funzione combinata con riferimenti a variabili definite fuori dalla funzione stessa. Le chiusure mantengono i riferimenti alla variabile, e questo permette loro di accedere alle variabili fuori dal loro ambito. "Racchiudono" la funzione e le variabili nel proprio ambiente.</p><h2 id="esempi-di-chiusure-in-javascript"><strong>Esempi di Chiusure in JavaScript</strong></h2><p>Probabilmente hai già incontrato e usato le chiusure senza neanche accorgertene. Vediamo alcuni altri modi per usarle.</p><h3 id="callback"><strong>Callback</strong></h3><p>Nelle funzioni callback è abituale far riferimento a una variabile dichiarata fuori dalla funzione stessa. Per esempio:</p><pre><code class="language-javascript">function getCarsByMake(make) {
	return cars.filter(x =&gt; x.make === make);
}</code></pre><p><code>make</code> è accessibile all'interno della funzione callback per via dell'ambito lessicale e il valore di <code>make</code> è preservato anche quando la funzione anonima è chiamata da <code>filter</code> grazie alla chiusura.</p><h3 id="memorizzazione-dello-stato"><strong>Memorizzazione dello stato</strong></h3><p>Possiamo usare le chiusure per restituire un oggetto che memorizzi lo stato da una funzione. Consideriamo la funzione <code>makePerson</code> qui di seguito, che restituisce un oggetto capace di memorizzare e cambiare il valore di <code>name</code>:</p><pre><code class="language-javascript">function makePerson(name) {
	let _name = name;

	return {
		setName: (newName) =&gt; (_name = newName),
		getName: () =&gt; _name,
	};
}

const me = makePerson("Zach");
console.log(me.getName()); // "Zach"

me.setName("Zach Snoek");
console.log(me.getName()); // "Zach Snoek"</code></pre><p>Questo esempio dimostra che quando creiamo una chiusura il valore delle variabili fuori dal suo ambito non viene congelato. La chiusura mantiene il riferimento a queste variabili per tutto il suo ciclo di vita.</p><h3 id="metodi-privati"><strong>Metodi privati</strong></h3><p>Se sei pratico di programmazione orientata agli oggetti, avrai notato che l'ultimo esempio ricorda una classe che memorizza lo stato privato ed espone metodi pubblici getter e setter. Possiamo estendere questo parallelismo con la programmazione orientata agli oggetti usando le chiusure per implementare i metodi privati:</p><pre><code class="language-javascript">function makePerson(name) {
	let _name = name;

	function privateSetName(newName) {
		_name = newName;
	}

	return {
		setName: (newName) =&gt; privateSetName(newName),
		getName: () =&gt; _name,
	};
}</code></pre><p><code>privateSetName</code> non è accessibile direttamente e può accedere alla proprietà privata <code>_name</code> tramite una chiusura.</p><h3 id="gestori-di-eventi-in-react"><strong>Gestori di Eventi in React</strong></h3><p>Infine, le chiusure sono usate abitualmente nei gestori di eventi in React. Il componente <code>Counter</code> qui di seguito è una variazione dalla <a href="https://reactjs.org/docs/hooks-reference.html#functional-updates">documentazione di React</a>:</p><pre><code class="language-jsx">function Counter({ initialCount }) {
	const [count, setCount] = React.useState(initialCount);

	return (
		&lt;&gt;
			&lt;button onClick={() =&gt; setCount(initialCount)}&gt;Reset&lt;/button&gt;
			&lt;button onClick={() =&gt; setCount((prevCount) =&gt; prevCount - 1)}&gt;
				-
			&lt;/button&gt;
			&lt;button onClick={() =&gt; setCount((prevCount) =&gt; prevCount + 1)}&gt;
				+
			&lt;/button&gt;
			&lt;button onClick={() =&gt; alert(count)}&gt;Show count&lt;/button&gt;
		&lt;/&gt;
	);
}

function App() {
	return &lt;Counter initialCount={0} /&gt;;
}</code></pre><p>Le chiusure permettono:</p><ul><li>ai gestori dell'evento click dei bottoni reset, decrement e increment di accedere a <code>setCount</code></li><li>al bottone reset di accedere a <code>initialCount</code> dalle proprietà di <code>Counter</code></li><li>e al bottone “Show count” di visualizzare lo stato <code>count</code>.</li></ul><p>Le Chiusure sono importanti anche in altre parti di React, come prop e hook. Questi temi non rientrano nell'ambito di questo articolo. Per saperne di più sul ruolo delle chiusure in React, raccomando la lettura di <a href="https://epicreact.dev/how-react-uses-closures-to-avoid-bugs/">questo post</a> di Kent C. Dodds o <a href="https://overreacted.io/making-setinterval-declarative-with-react-hooks/">questo post</a> di Dan Abramov.</p><h2 id="conclusione"><strong>Conclusione</strong></h2><p>L'ambito di visibilità è la parte di un programma da cui abbiamo accesso a una variabile. JavaScript ci permette di annidare gli ambiti di visibilità, e le variabili dichiarate in un ambito esterno sono accessibili da uno interno. Le variabili possono avere ambito di visibilità globale, di modulo o di blocco.</p><p>Una chiusura è una funzione che racchiude un riferimento a una variabile dichiarata in un ambito di visibilità esterno ad essa. Le chiusure permettono alle funzioni di mantenere una connessione con delle variabili esterne, anche fuori dall'ambito di visibilità delle variabili stesse.</p><p>Esistono molteplici usi per le chiusure, dalla creazione di strutture simili alle classi che memorizzano lo stato e implementano metodi privati, al passare funzioni callback ai gestori di eventi.</p><h2 id="connettiamoci"><strong>Connettiamoci</strong></h2><p>Se sei interessato ad altri articoli come questo, <a href="https://mailchi.mp/2df4b6d5458f/signup-page">iscriviti alla mia newsletter</a> e seguimi su <a href="https://www.linkedin.com/in/zach-snoek-5b327b179/">LinkedIn</a> e <a href="https://twitter.com/zach_snoek">Twitter</a>!</p><h2 id="ringraziamenti"><strong>Ringraziamenti</strong></h2><p>Grazie a <a href="https://github.com/bryanrsmith">Bryan Smith</a> per avermi dato dei feedback sulle bozze di questo post.</p><p>Foto di <a href="https://unsplash.com/@kar111?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Karine Avetisyan</a> su <a href="https://unsplash.com/s/photos/chain?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Come Costruire una App Web per il Logging con Server-Sent Events, RxJS ed Express ]]>
                </title>
                <description>
                    <![CDATA[ Diciamo che stai lavorando alla tua nuova grande idea - una app web o mobile e un server back-end. Fin qui niente di complicato. Fino a che non ti rendi conto che hai bisogno di inviare dati dal tuo server ai client. Normalmente, per cose del genere, la prima cosa ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-costruire-una-app-web-per-il-logging-con-server-sent-events-rxjs-ed-express/</link>
                <guid isPermaLink="false">63e3b1c30916b8062b0a33fc</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paolo Pescosolido ]]>
                </dc:creator>
                <pubDate>Thu, 09 Feb 2023 18:02:20 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/02/Frame-11.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/build-a-logging-web-app-with-server-sent-events-rxjs-and-express/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build a Logging Web App with Server-Sent Events, RxJS, and Express</a>
      </p><p>Diciamo che stai lavorando alla tua nuova grande idea - una app web o mobile e un server back-end. Fin qui niente di complicato. Fino a che non ti rendi conto che hai bisogno di inviare dati dal tuo server ai client.</p><p>Normalmente, per cose del genere, la prima cosa che ti salta alla mente è di usare strumenti affidabili, come WebSockets, SocketIO, o addirittura un servizio a pagamento che se ne occupa al posto tuo.</p><p>Ma esiste un altro metodo che normalmente viene lasciato da parte, di cui potresti anche non averne mai sentito parlare finora. Si chiama SSE, abbreviazione di Server-Sent Events (Eventi Inviati dal Server).</p><p>SSE occupa un posto speciale nel mio cuore, grazie alla sua semplicità. È leggero, efficiente e molto potente.</p><p>Per spiegare in dettaglio SSE e come lo utilizzo, esaminerò un mio piccolo progetto parallelo che penso sia un eccellente esempio di SSE. Utilizzerò Typescript, Express e RxJS, quindi prepara il tuo ambiente di lavoro e allaccia le cinture perché stiamo per tuffarci nel codice.</p><p>Prima di iniziare, c'è una cosa che devi sapere su SSE. Come suggerisce il suo nome, Server-Sent Events è unidirezionale dal server al client. Se il tuo client avesse bisogno di inviare dati in risposta al server, SSE non è una soluzione adatta alle tue esigenze. Ma nella maggior parte degli scenari non è un requisito necessario e possiamo usare REST per inviare dati in risposta al server.</p><h2 id="qual-il-progetto"><strong>Qual è il progetto?</strong></h2><p>L'idea di questo progetto è semplice: ho un sacco di script che girano su Raspberry Pis, droplet su Digital Ocean e altri posti che non mi sono facilmente accessibili. Quindi ho bisogno di un modo per salvare i log e accedervi da qualsiasi parte.</p><p>La soluzione che cerco è una semplice app web che riceva i log e un collegamento diretto alla mia sessione che possa aprire su qualsiasi dispositivo o anche condividere con altre persone.</p><p>Ci sono un paio di cose da tenere a mente prima di andare avanti.</p><p>Primo, i log che ricevo dai miei script non sono molto frequenti, e la complicazione di usare HTTP è trascurabile nel mio caso specifico. Per questo, ho deciso di pubblicare i miei log in una API REST di base e usare SSE nel lato client per registrare i log in arrivo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/02/Frame-8-1.png" class="kg-image" alt="Frame-8-1" width="600" height="400" loading="lazy"><figcaption>Esempio di logging</figcaption></figure><p>Secondo, questo strumento serve per un debug rapido di cose su cui sto lavorando. Esistono svariati strumenti professionali che potrei utilizzare. Ma volevo qualcosa di veramente leggero e facile da usare.</p><h2 id="scriviamo-un-po-di-codice-lato-server"><strong>Scriviamo un po' di codice lato Server</strong></h2><p>La configurazione lato server è semplice. Quindi iniziamo con un diagramma per darti un'idea del setup prima di spiegare tutto più dettagliatamente.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/02/Frame-10-1.png" class="kg-image" alt="Frame-10-1" width="600" height="400" loading="lazy"><figcaption>Diagramma del server</figcaption></figure><p>Se pensiamo al nostro server back-end come a una pipeline, da un lato abbiamo una serie di publisher (editori) - nel nostro caso gli script che pubblicano i log. Dall'altro abbiamo i client che registrano questi log.</p><p>Per connettere questi due vertici, userò un Soggetto RxJS. Questo mi permetterà di pubblicare qualsiasi cosa dall'editore tramite REST e in seguito registrare questi eventi e girare i messaggi ai client tramite SSE.</p><p>Per iniziare, definiamo la nostra interfaccia Log. Per mantenere le cose semplici, definirò solo il campo content che conterrà le informazioni del log.</p><pre><code class="language-ts">interface Log {
  content: string;
}</code></pre><h3 id="come-configurare-rxjs"><strong>Come configurare RxJS</strong></h3><p>Importiamo RxJS, creiamo un nuovo Subject per i nostri Log e definiamo una funzione per pubblicare i log su questo Subject.</p><p>Ovviamente, potremmo esportare il nostro Subject e chiamarlo direttamente dal nostro router, ma io preferisco astrarre l'implementazione e fornire solamente la funzione emit al resto del mio codice.</p><pre><code class="language-ts">import { Subject } from 'rxjs';

// Log Subject
const NewLog$ = new Subject&lt;Log&gt;();

/**
 * Emit a new log to the RxJS subject
 * @param log
 */
export function emitNewLog(log: Log): void {
    NewLog$.next(log);
}</code></pre><p>E per finire, definiamo una nuova rotta nel server di Express che accetti i nuovi log dai nostri client e li pubblichi tramite il metodo emitNewLog che abbiamo appena creato.</p><pre><code class="language-ts">app.post('/', (req: Request, res: Response) =&gt; {
  const content = req.body.content;
  const log: Log = { content: content };
  emitNewLog(log);
  return res.status(200).json({ ok: true });
});</code></pre><p>Adesso siamo pronti con la parte riguardante la pubblicazione. Quello che rimane da fare è definire la rotta SSE, registrare il Subject RxJS e inviare i log ai nostri client.</p><h3 id="come-configurare-la-rotta-sse"><strong>Come configurare la rotta SSE</strong></h3><p>Iniziamo con la definizione di una nuova rotta per la nostra connessione SSE. Per abilitare SSE, abbiamo bisogno di inviare un paio di header ai client.</p><p>Vogliamo l'header <strong><strong>‘Connection’</strong> </strong>impostato su <strong><strong>‘keep-alive’</strong></strong>, <strong><strong>‘Cache-Control’</strong> </strong>su ‘<strong><strong>no-cache</strong></strong>’ e <strong><strong>‘Content-Type’</strong></strong> su <strong><strong>‘text/event-stream’</strong></strong>. In questa maniera il client saprà che questa è una rotta SSE.</p><p>Inoltre, ho aggiunto <strong><strong>‘Access-Control-Allow-Origin’</strong></strong> per CORS e <strong><strong>‘X-Accel-Buffering’</strong></strong> impostato su <strong><strong>‘no’</strong></strong> per evitare che <a href="https://www.nginx.com/">Nginx</a> si intrometta in questa rotta. E per finire possiamo reinviare gli header al nostro client per iniziare il flusso di eventi.</p><pre><code class="language-ts">app.get('/', (req: Request, res: Response) =&gt; {
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Connection', 'keep-alive');
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('X-Accel-Buffering', 'no');
  res.flushHeaders();
});</code></pre><p>Adesso possiamo iniziare a inviare dati inserendoli nella nostra risposta.</p><p>SSE utilizza un protocollo di testo che possiamo usare per aiutare il client a differenziare fra i vari tipi di eventi. Ognuno dei nostri eventi dovrebbe avere questa struttura:</p><pre><code class="language-ts">event: ${event name}\n
data: ${event data}\n\n</code></pre><p>Per facilitarmi la vita, ho creato una funzione che si occupa della serializzazione al posto mio.</p><pre><code class="language-ts">/**
 * SSE message serializer
 * @param event: Event name
 * @param data: Event data
 */
function serializeEvent(event: string, data: any): string {
  const jsonString = JSON.stringify(data);
  return `event: ${event}\ndata: ${jsonString}\n\n`;
}</code></pre><p>Ora possiamo registrare il Subject RxJS che abbiamo creato prima, serializzare ogni nuovo log e girarlo sulla nostra connessione come un evento <strong><strong>NEW_LOG</strong></strong>.</p><pre><code class="language-ts">app.get('/', (req: Request, res: Response) =&gt; {
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Connection', 'keep-alive');
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('X-Accel-Buffering', 'no');
  res.flushHeaders();

  NewLog$.subscribe((log: Log) =&gt; {
    res.write(serializeEvent('NEW_LOG', log));
  });

}</code></pre><p>Per ultimo dobbiamo assicurarci di cancellare la registrazione dell'osservatore quando la connessione SSE viene chiusa:</p><pre><code class="language-ts">app.get('/', (req: Request, res: Response) =&gt; {
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Connection', 'keep-alive');
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('X-Accel-Buffering', 'no');
  res.flushHeaders();

  const stream$ = NewLog$.subscribe((log: Log) =&gt; {
    res.write(serializeEvent('NEW_LOG', log));
  });

  req.on('close', () =&gt; {
    stream$.unsubscribe();
  });
});</code></pre><p>E questo è tutto! Abbiamo finito con il nostro server ed è ora di occuparci del codice front-end.</p><h2 id="scriviamo-il-codice-del-client"><strong>Scriviamo il codice del client</strong></h2><p>Registrare la rotta SSE dal browser è semplicissimo. Per prima cosa, spostiamoci sul codice del client e creiamo una nuova istanza dell'interfaccia <strong><strong>EventSource</strong></strong> e passiamo il nostro endpoint come argomento del constructor.</p><pre><code class="language-js">const eventSource = new EventSource("/");</code></pre><p>Quindi, possiamo aggiungere gli event listeners per gli eventi che vogliamo registrare (nel nostro caso, <strong><strong>NEW_LOG</strong></strong>) e definiamo un metodo callback per gestire il nostro log.</p><pre><code class="language-js">eventSource.addEventListener(
   "NEW_LOG", (event) =&gt; {
       const log = JSON.parse(event.data);
       // use the data to update the UI
    }, false
);</code></pre><p>E per finire, &nbsp;possiamo chiudere la connessione appena abbiamo finito di osservare questi eventi.</p><pre><code class="language-js">eventSource.close();</code></pre><h2 id="conclusione"><strong>Conclusione</strong></h2><p>Come puoi vedere, i Server-Sent Events rendono veramente facile inviare contenuto dal server verso il client. Sono particolarmente utili perché abbiamo un'interfaccia integrata nella maggior parte dei browser moderni, e possiamo facilmente usare un polyfill per quelli che non la forniscono.</p><p>Inoltre, SSE gestisce automaticamente le riconnessioni al posto nostro, nel caso in cui il client perdesse la connessione al server. Perciò, è una valida alternativa a SocketIO e WebSockets in vari scenari in cui si ha bisogno di un flusso di dati unidirezionale dal server.</p><p>Se sei interessato in questo progetto, ho aggiunto un paio di funzionalità extra al codice che abbiamo appena visto e un'interfaccia grafica che puoi vedere qui: <a href="https://logsnag.com/console">LogSnag Console</a>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/02/Frame-9-1.png" class="kg-image" alt="Frame-9-1" width="600" height="400" loading="lazy"><figcaption>Console demo</figcaption></figure> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Optional Chaining `?.` – Come Funziona e Quando Usarlo ]]>
                </title>
                <description>
                    <![CDATA[ Cos'è l'optional chaining? L'optional chaining (concatenamento opzionale), rappresentato da ?. in JavaScript, è una nuova funzionalità introdotta con ES2020. L'optional chaining cambia la maniera in cui accedere alle proprietà in oggetti annidati in profondità. Risolve il problema di dover fare molteplici controlli per valori nulli quando si accede a una ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/optional-chaining-in-javascript/</link>
                <guid isPermaLink="false">63e29f0b0916b8062b0a31fe</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paolo Pescosolido ]]>
                </dc:creator>
                <pubDate>Wed, 08 Feb 2023 09:34:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/02/optional.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/javascript-optional-chaining-explained/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">JavaScript Optional Chaining `?.` Explained - How it Works and When to Use it</a>
      </p><h2 id="cos-l-optional-chaining"><strong>Cos'è l'optional chaining?</strong></h2><p>L'optional chaining (concatenamento opzionale), rappresentato da <code>?.</code> in JavaScript, è una nuova funzionalità introdotta con ES2020.</p><p>L'optional chaining cambia la maniera in cui accedere alle proprietà in oggetti annidati in profondità. Risolve il problema di dover fare molteplici controlli per valori nulli quando si accede a una lunga catena di proprietà in JavaScript.</p><p>Stato attuale: <code>stadio 4 del processo di approvazione ECMAScript</code>: <a href="https://github.com/tc39/proposal-optional-chaining">https://github.com/tc39/proposal-optional-chaining</a></p><h2 id="casi-d-uso"><strong>Casi d'uso</strong></h2><ol><li>Accedere alle proprietà di un oggetto con valore potenzialmente &nbsp;<code>null</code> o <code>undefined</code>.</li><li>Ottenere risultati da una variabile che potrebbe non essere ancora disponibile.</li><li>Ottenere valori di default.</li><li>Accedere a lunghe catene di proprietà.</li></ol><p>Immagina che come risposta di una API ti aspetti un oggetto di questo tipo:</p><pre><code class="language-javascript">obj = {
  prop1: {
    prop2: {
      someProp: "value"
    }
  }
};
</code></pre><p>Ma potresti non sapere in anticipo se ognuno di questi campi è disponibile. Alcuni potrebbe non essere inclusi nella risposta dell'API, o potrebbero contenere valori nulli.</p><p>Per esempio:</p><pre><code class="language-javascript">//risposta attesa
obj = {
  id: 9216,
  children: [
    { id: 123, children: null },
    { id: 124, children: [{ id: 1233, children: null }] }
  ]
};

//risposta ottenuta
obj = {
  id: 9216,
  children: null
};
</code></pre><p>Questo succede spesso con funzioni che accedono a una API. Forse ti è capitato di vedere del codice di React che cerca di salvaguardarsi da questo tipo di problema nella seguente maniera:</p><pre><code class="language-jsx">render = () =&gt; {
  const obj = {
    prop1: {
      prop2: {
        someProp: "value",
      },
    },
  };

  return (
    &lt;div&gt;
      {obj &amp;&amp; obj.prop1 &amp;&amp; obj.prop1.prop2 &amp;&amp; obj.prop1.prop2.someProp &amp;&amp; (
        &lt;div&gt;{obj.prop1.prop2.someProp}&lt;/div&gt;
      )}
    &lt;/div&gt;
  );
};

</code></pre><p>In passato, per prepararsi ad affrontare questo problema, abbiamo spesso usato <code>Lodash</code>, e più precisamente il metodo <code>_.get</code>:</p><pre><code class="language-javascript">_.get(obj, prop1.prop2.someProp);

</code></pre><p>Questo metodo ritorna <code>undefined</code> se una qualunque di quelle proprietà è <code>undefined</code>. <strong>L'o<strong>ptional chaining </strong>è esattamente questo</strong>! Adesso invece di usare una libreria esterna, questa funzionalità è integrata.</p><h2 id="come-funziona-l-optional-chaining"><strong>Come funziona l'optional chaining?</strong></h2><p><code>?.</code> può essere usato per concatenare proprietà che potrebbero avere un valore <code>null</code> o <code>undefined</code>.</p><pre><code>const propNeeded = obj?.prop1?.prop2?.someProp;

</code></pre><p>Se una qualsiasi di queste proprietà contenesse un valore <code>null</code> o <code>undefined</code>, JavaScript ritornerebbe <code>undefined</code>.</p><p>E se invece volessimo restituire qualcosa di significativo? Puoi provare così:</p><pre><code class="language-javascript">let alberoGenealogico = {
    noi: {
        figli: {}
    }
}


// con il metodo _.get
const nipoti = _.get(alberoGenealogico, 'noi.figli.loroFigli', 'non hanno avuto figli' );

//con optional chaining e null coalescing 
const nullCoalescing = alberoGenealogico?.noi?.figli?.loroFigli ?? 'non hanno avuto figli'
console.log(nullCoalescing) //non hanno avuto figli
</code></pre><p>Funziona anche con oggetti che potrebbero essere <code>null</code> o <code>undefined</code>:</p><pre><code>let user;
console.log(user?.id) // undefined

</code></pre><h2 id="come-ottenere-questa-nuova-funzionalit-"><strong>Come ottenere questa nuova funzionalità</strong></h2><ol><li>Provala nella console del tuo browser: essendo un'aggiunta recente, un browser risalente potrebbe necessitare di polyfill. Puoi provarlo nella console di browser come Chrome o Firefox. Se non funzionasse ancora, puoi provare ad abilitare le funzionalità sperimentali di JavaScript visitando <code>chrome://flags/</code> e abilitando "Experimental JavaScript".</li><li>Puoi provarlo nella tua app di Node usando Babel:</li></ol><pre><code>{
  "plugins": ["@babel/plugin-proposal-optional-chaining"]
}
</code></pre><h2 id="risorse"><strong>Risorse</strong></h2><p><a href="https://dmitripavlutin.com/javascript-optional-chaining/">ttps://dmitripavlutin.com/javascript-optional-chaining/</a></p><ol><li>Documentazione di Babel: <a href="https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining">https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining</a></li></ol><h2 id="tl-dr"><strong>TL;DR</strong></h2><p>Usa optional chaining <code>?.</code> con oggetti o lunghe concatenazioni di proprietà che potrebbero contenere un valore <code>null</code> o <code>undefined</code>. La sintassi è la seguente:</p><pre><code class="language-javascript">let user = {};
console.log(user?.id?.name) </code></pre> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
