【发布时间】:2020-05-23 12:33:34
【问题描述】:
我生成了许多具有相同内容和 150M 大小的文件。
我使用fs.readFile async API 像这样读取它们:
const fs = require('fs');
const COUNT = 16;
for (let i = 1; i <= COUNT; ++i) {
console.time(i);
console.log(process.hrtime());
fs.readFile(`a${i}`, (err, data) => {
console.log(process.hrtime());
console.timeEnd(i);
});
}
我已将 ENV 变量 UV_THREADPOOL_SIZE 设置为 1。然后将 COUNT 更改为 8、16 甚至 128。
但回调似乎几乎同时触发。对于128,时间超过4s。
我只测试了 1 个文件,大约需要 60 毫秒。这个截图是 8 个文件的结果:
在我的记忆中,异步fs.readFile API 是由线程池处理的。所以我将池大小更改为 1。
并且在 NodeJS 事件循环中,poll 阶段会处理 IO 事件并为它们执行回调。我忘记了轮询阶段会阻塞事件循环多长时间。但我猜不到 4s。
所以对于上面的代码,我们想异步读取文件。他们同时启动,排队等候接机。由于 poll 大小是 1,我想我们会一个一个地读取所有文件,对吧?如果一个文件已经读取,回调将在下一个轮询阶段执行(对于128个文件,时间超过4s,所以我猜会有下一个轮询阶段)。然后我们将在控制台中获取时间。
但我不明白输出。似乎几乎同时触发了回调。
我对事件循环中的轮询阶段或线程池有什么错误吗?
更新:我知道我可以使用流来优化读取大文件。但问题是当我将线程池设置为 1 时,异步 API 似乎是并行运行的。
更新:感谢@O 的回答。琼斯。他告诉我,nodejs 在读取文件时交错了这些小块。有人可以帮我给我一些关于它的资源吗?或者有谁知道其他信息?
【问题讨论】:
标签: node.js callback threadpool fs event-loop