Per capire cosa stava succedendo di sicuro, avevo bisogno di apportare alcune modifiche al tuo script, ma qui ci sono.
Innanzitutto, potresti sapere come node
e come event loop
funziona, ma fammi fare un breve riepilogo. Quando si esegue uno script, node
runtime prima eseguire la parte sincrona di esso quindi pianificare l' promises
e timers
da eseguire sulle prossime loop, e quando selezionato si risolvono, eseguire i callback in un altro ciclo. Questo semplice riassunto lo spiega molto bene, merito a @StephenGrider:
const pendingTimers = [];
const pendingOSTasks = [];
const pendingOperations = [];
// New timers, tasks, operations are recorded from myFile running
myFile.runContents();
function shouldContinue() {
// Check one: Any pending setTimeout, setInterval, setImmediate?
// Check two: Any pending OS tasks? (Like server listening to port)
// Check three: Any pending long running operations? (Like fs module)
return (
pendingTimers.length || pendingOSTasks.length || pendingOperations.length
);
}
// Entire body executes in one 'tick'
while (shouldContinue()) {
// 1) Node looks at pendingTimers and sees if any functions
// are ready to be called. setTimeout, setInterval
// 2) Node looks at pendingOSTasks and pendingOperations
// and calls relevant callbacks
// 3) Pause execution. Continue when...
// - a new pendingOSTask is done
// - a new pendingOperation is done
// - a timer is about to complete
// 4) Look at pendingTimers. Call any setImmediate
// 5) Handle any 'close' events
}
// exit back to terminal
Si noti che il ciclo degli eventi non finirà mai fino a quando non saranno presenti attività del sistema operativo in sospeso. In altre parole, l'esecuzione del nodo non finirà mai fino a quando non saranno presenti richieste HTTP in sospeso.
Nel tuo caso, esegue una async
funzione, poiché restituirà sempre una promessa, pianificherà che venga eseguita nella successiva iterazione del ciclo. Sulla tua funzione asincrona, pianifichi altre 1000 promesse (richieste HTTP) contemporaneamente in quella map
iterazione. Dopodiché, stai aspettando che tutto sia risolto per terminare il programma. Funzionerà sicuramente, a meno che la tua funzione di freccia anonima sul map
non generi alcun errore . Se una delle tue promesse genera un errore e non le gestisci, alcune delle promesse non avranno il loro callback chiamato mai facendo terminare il programma ma non uscire , perché il loop degli eventi gli impedirà di uscire fino a quando non si risolve tutte le attività, anche senza richiamata. Come dice ilPromise.all
documenti : verrà rifiutato non appena la prima promessa verrà rifiutata.
Quindi, il tuo ECONNRESET
errore on non è correlato al nodo stesso, è qualcosa con la tua rete che ha fatto il recupero per generare un errore e quindi impedire la fine del ciclo degli eventi. Con questa piccola correzione, sarai in grado di vedere tutte le richieste che vengono risolte in modo asincrono:
const fetch = require("node-fetch");
(async () => {
try {
const promises = Array(1000)
.fill(1)
.map(async (_value, index) => {
try {
const url = "https://google.com/";
const response = await fetch(url);
console.log(index, response.statusText);
return response;
} catch (e) {
console.error(index, e.message);
}
});
await Promise.all(promises);
} catch (e) {
console.error(e);
} finally {
console.log("Done");
}
})();
npx envinfo
, eseguendo il tuo esempio sul mio script Win 10 / nodev10.16.0 termina in 8432.805ms