Pour comprendre ce qui se passait à coup sûr, j'ai dû apporter quelques modifications à votre script, mais les voici.
Tout d'abord, vous savez peut-être comment node
et son event loop
fonctionnement, mais permettez-moi de faire un bref résumé. Lorsque vous exécutez un script, le node
runtime exécute d'abord la partie synchrone de celui-ci, puis planifie le promises
et timers
à exécuter sur les boucles suivantes et, une fois vérifiés, ils sont résolus, exécutez les rappels dans une autre boucle. Ce simple résumé l'explique très bien, crédit à @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
Notez que la boucle d'événements ne se terminera jamais tant qu'il n'y aura pas de tâches OS en attente. En d'autres termes, l'exécution de votre nœud ne se terminera jamais tant qu'il n'y aura pas de requêtes HTTP en attente.
Dans votre cas, il exécute une async
fonction, car il retournera toujours une promesse, il planifiera son exécution dans la prochaine itération de la boucle. Sur votre fonction asynchrone, vous planifiez 1000 autres promesses (requêtes HTTP) à la fois dans cette map
itération. Après cela, vous attendez tout, puis être résolu pour terminer le programme. Cela fonctionnera, bien sûr, à moins que votre fonction de flèche anonyme sur le map
ne génère aucune erreur . Si l' un de vos promesses renvoie une erreur et vous ne manipulez pas, certaines des promesses ne génèreront pas de rappel appelé jamais rendre le programme à la fin , mais pas à la sortie , car la boucle d'événements qui l' empêchera de sortie jusqu'à ce qu'il décide toutes les tâches, même sans rappel. Comme il est dit sur lePromise.all
docs : il sera rejeté dès que la première promesse sera rejetée.
Ainsi, votre ECONNRESET
erreur d' erreur n'est pas liée au nœud lui-même, c'est quelque chose avec votre réseau qui a effectué la récupération pour générer une erreur, puis empêcher la boucle d'événement de se terminer. Avec ce petit correctif, vous seriez en mesure de voir toutes les demandes résolues de manière asynchrone:
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
exécution de votre exemple sur mon script Win 10 / nodev10.16.0 se termine en 8432.805ms