Чтобы понять, что происходит наверняка, мне нужно было внести некоторые изменения в ваш скрипт, но здесь есть.
Во-первых, вы можете знать, как работает node
и event loop
, но позвольте я сделаю быстрое резюме. Когда вы запускаете сценарий, node
runtime сначала запускает его синхронную часть, а затем назначает выполнение promises
и timers
в следующих циклах, а когда проверено, разрешены ли они, запускайте обратные вызовы в другом l * 1034. *. Это простое объяснение очень хорошо объясняет, кредит @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
Обратите внимание, что событие l oop никогда не закончится, пока не будут выполнены задачи ОС. Другими словами, выполнение вашего узла никогда не закончится, пока не будут получены ожидающие HTTP-запросы.
В вашем случае он выполняет функцию async
, так как он всегда будет возвращать обещание, он будет планировать его выполняется в следующей итерации l oop. В вашей функции asyn c вы запланируете еще несколько 1000 обещаний (HTTP-запросов) сразу в этой итерации map
. После этого вы ждете, пока все решится на окончание sh программы. Это будет работать наверняка, если только ваша анонимная функция стрелки на map
не выдаст ошибку . Если одно из ваших обещаний выдает ошибку, а вы ее не обрабатываете, некоторым обещаниям не будет вызываться обратный вызов, когда программа будет end , но не exit , потому что событие l oop будет препятствовать его выходу, пока оно не решит все задачи, даже без обратного вызова. Как сказано в Promise.all
документах : он будет отклонен, как только отклоняется первое обещание.
Итак, ваша ошибка on ECONNRESET
не связана с самим узлом, это нечто с вашей сетью, которая произвела выборку, чтобы выдать ошибку, а затем предотвратить завершение события l oop. С помощью этого небольшого исправления вы сможете увидеть все запросы, решаемые асинхронно:
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");
}
})();