为了确定发生了什么,我需要对您的脚本进行一些修改,但是这里有。
首先,您可能知道node
其event loop
工作方式及其工作原理,但让我快速回顾一下。运行脚本时,node
运行时首先运行它的同步部分,然后计划promises
和timers
在下一个循环中执行,并且在检查了它们的解析后,在另一个循环中运行回调。这个简单的要点很好地解释了它,归功于@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
请注意,事件循环永远不会结束,直到有待处理的OS任务。换句话说,您的节点执行将永远不会结束,直到有未决的HTTP请求。
在您的情况下,它运行一个async
函数,因为它将始终返回promise,并将其安排在下一个循环迭代中执行。在异步功能上,您可以在该迭代中一次安排另外1000个 Promise(HTTP请求)map
。之后,您正在等待所有解决方案完成。除非您的匿名箭头功能map
不会引发任何错误,否则它将肯定起作用。如果您的一个诺言引发错误并且您没有处理错误,则某些诺言将不会调用它们的回调,从而使程序结束但不退出,因为事件循环将阻止它退出,直到解决为止所有任务,即使没有回调。正如它在Promise.all
docs:第一个诺言被拒绝时,它会被拒绝。
因此,您的on ECONNRESET
错误与节点本身无关,与您的网络有关,它使获取操作抛出错误,然后阻止事件循环结束。有了这个小修正,您将能够看到所有请求都被异步解决:
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
,运行在我赢得10 / nodev10.16.0脚本结束你的例子在8432.805ms