我需要澄清一些关于 Node.js、Promises、CPU 和性能的事情。
要建立一个上下文,我会说一个异步处理(数据库查询)执行多次(在一个循环中)然后在所有异步之后才做其他事情。处理完成。
让我们从一个代码示例开始:
async function databaseQuery() {
return await connection.query('SELECT * FROM example;');
}
我想执行 n 次异步调用(databaseQuery
函数),当这些 n 次执行结束时,再做一些其他事情。
让我们使用类似的 Promises 来实现这个目标:
const array = [...]; // Assuming this array is full of whatever
const promises = array.map(async (item) => {
return await databaseQuery();
});
await Promise.all(promise);
// Ok now I'm sure all async calls are done
我尝试在两个环境中实现此代码:
- 本地计算机,Windows 10 x64,Intel i7 6c/12t,16g 内存
- 远程服务器(虚拟化服务器@OVH)、Ubuntu 16.04、1vCore、6g RAM
显然,本地机器上的性能远远好于远程机器(< 1 秒对 > 1 分钟)。
但我需要一些关于为什么? 的精确度。我知道物理 Material 在本地机器上更好。
此外,由于 Node.js 在单个内核上的单个线程上运行,为什么 Windows 资源使用 10 个线程和 6 个处理器监视 Node.js 进程?
代码中没有实现“多处理”代码(例如使用cluster
)。
如果我想把这段代码投入生产,我应该注意处理器的核心数,还是 Windows 内部进程管理?
请帮我澄清一下这种情况,我真的很想了解这在后台是如何工作的,因为这将有助于选择正确的配置来运行此类代码。
最佳答案
Node.js 在单个线程中运行您放入其中的 JavaScript,但它有更多线程执行 I/O 和微任务队列的各种任务。在我写这个答案的时候,Node.js 总是至少有 7 个线程:4 个用于 libuv 事件循环[1],4 个用于运行 V8 的后台任务[2],1 个用于调度延迟的 V8 后台任务.
您的数据库库、其他插件或 Node.js 核心中的杂项可能会出于各种原因创建额外的线程。
这显示为多核利用率,因为(简单来说)CPU 将围绕核心传递线程。
作为旁注,return await
is completely unneeded ,您可以从异步函数返回 promise ,它们将被解包,因为 promise 解析是平面映射操作。
[1] libuv 处理 I/O,例如从文件读取、创建 tcp 套接字和调度计时器。
[2] V8 后台任务包括运行垃圾收集器和优化代码。
关于javascript - promise 并行性和 CPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51362308/