forEach/map e async non vanno di pari passo

Intestazione

A volte, tendiamo spesso a passare funzioni asincrone con funzioni forEach e map.

Per es:

[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));

Risultato: tutti i numeri da 1 a 5 vengono stampati uno dopo l'altro ma non c'è intervallo di 1 secondo dopo la stampa di ciascuna riga.

Perché succede?

Guarda questa funzione javascript:

async function doubleOf(n) {
  return n*2;
}

Risultato: questo in realtà restituisce una Promessa che si risolve in un numero.

Se scriviamo un equivalente Typescript di questa funzione con tipi rigorosi, chiarirà le cose.

Il seguente codice non verrà compilato:

async function doubleOf(n: number): number {
  return n*2;
}

La versione corretta sarebbe:

async function doubleOf(n: number): Promise<number> {
  return n*2;
}

Non lasciarti ingannare dallo zucchero sintattico fornito da async-await. Se scrivessimo promesse pure senza usare async, la funzione sopra sarebbe simile a:

function doubleOf(n) {
  return new Promise((resolve) => resolve(n*2));
}

function doubleOf(n: number): Promise<number> {
  return new Promise((resolve) => resolve(n*2));
}

le funzioni asincrone restituiscono promesse e non valori
  1. Abbiamo doubleOfuna funzione che accetta un numero e restituisce un numero. Semplice vecchio javascript.
  2. Abbiamo doubleOfOldWayuna funzione che accetta un numero e restituisce una promessa che si risolve in un numero.
  3. Abbiamo doubleOfNewWay, una funzione asincrona che accetta un numero e sembra che restituisca un numero, ma in realtà restituisce una promessa che si risolve in un numero proprio come la doubleOfOldWayfunzione.
  4. doubleOfOldWaye doubleOfNewWayle funzioni sono esattamente le stesse.
  5. E quindi, quando proviamo ad eseguire un'operazione di moltiplicazione sui valori restituiti da doubleOfOldWaye doubleOfNewWayfunzioni, il risultato è stato NaN, poiché non possiamo più promesse (ovviamente!).
  6. Moltiplicare doubleOfOldWaye doubleOfNewWay:

Quindi torniamo al nostro esempio iniziale:

[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));

Il modo più corretto per implementare ciò che ci aspettiamo da questa funzione forEach è usare un semplice ciclo for:

for(const number of [1,2,3,4,5]) {
    console.log(number);
    await new Promise(resolve => setTimeout(resolve, 1000)); // Sleep for "atleast" 1 second
}

[1,2,3,4,5].map(async (n) => n*2);

(5) [Promise, Promise, Promise, Promise, Promise]
0: Promise {<fulfilled>: 2}
1: Promise {<fulfilled>: 4}
2: Promise {<fulfilled>: 6}
3: Promise {<fulfilled>: 8}
4: Promise {<fulfilled>: 10}

Per ottenere un elenco di doppio di ogni numero, quello che possiamo fare è:

await Promise.all([1,2,3,4,5].map(async (n) => n*2));

[2, 4, 6, 8, 10]

Suggested posts

Ricerca di informazioni sui nomi di dominio

Un estratto da Small, Sharp Software Tools di Brian P. Hogan

Ricerca di informazioni sui nomi di dominio

Quando fai una richiesta a facebook.com, il tuo computer cerca il nome di dominio per tradurre quel nome di dominio in un indirizzo IP in modo che il tuo computer possa effettuare quella connessione.

La parola D e la parola L in UI Design. Questioni linguistiche. Non essere razzista.

La parola D e la parola L in UI Design. Questioni linguistiche. Non essere razzista.

La nostra lingua è uno strumento potente che può modellare i nostri pensieri, atteggiamenti e azioni. Anche termini apparentemente innocui possono perpetuare pregiudizi e stereotipi dannosi.

Related posts

Quell'archivio di minaccia: Vol 7 Black Basta

Quell'archivio di minaccia: Vol 7 Black Basta

Nel mondo interconnesso di oggi, la minaccia degli attacchi informatici è più diffusa che mai. I criminali informatici e gli attori dello stato-nazione cercano costantemente di sfruttare le vulnerabilità e rubare dati preziosi, ponendo un rischio significativo per le organizzazioni di tutte le dimensioni.

La sfida di lettura di Goodreads è tossica

La sfida di lettura di Goodreads è tossica

Il prurito alla mano si diffuse mentre mercanteggiavo con il libraio locale per un altro libro. Questo libro, come il resto che ho acquistato di recente, troverebbe il suo trono nella mia pila "Da leggere" (TBR); eppure l'ho comprato.

Tieni traccia di chiunque abbia solo un numero di telefono | Indagine OSINT

Tieni traccia di chiunque abbia solo un numero di telefono | Indagine OSINT

Puoi essere un investigatore OSINT, un giocatore CTF o semplicemente qualcuno che riceve chiamate spam. Qualcuno che sta cercando di verificare il numero che hai visto in una pubblicità.

Niente più password: come le passkey sostituiranno la tua password

Niente più password: come le passkey sostituiranno la tua password

Per evitare ambiguità verranno utilizzati i seguenti termini; Autenticatore; Il telefono cellulare utilizzato per effettuare il login Sito web; Il sito Web o l'applicazione che l'utente sta utilizzando per effettuare la richiesta di accesso al Servizio; Il fornitore che fornisce il servizio dato, ad es