我需要澄清一些有关Node.js,Promises,CPU和性能的信息。
要设置上下文,我将讨论多次(循环)执行一次异步处理(数据库查询),然后仅在全部异步后再执行其他操作。处理完成。
让我们从一个代码示例开始:
async function databaseQuery() {
return await connection.query('SELECT * FROM example;');
}
我想执行一次 n 次异步调用(databaseQuery
函数),并且当这些 n 执行结束时,执行其他操作。
让我们使用并行 Promise 实现这一目标:
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
我尝试在两个环境中实现此代码:
很明显,本地计算机的性能要比远程计算机好得多(<1秒vs.> 1分钟)。
但是我需要关于为什么?的一些精度。我知道物理材料在本地计算机上会更好。
此外,由于Node.js在单个内核上的单个线程上运行,为什么Windows资源使用10个线程和6个处理器监视Node.js进程?
该代码中没有实现“多处理”代码(例如,使用cluster
)。
如果我想将此代码投入生产,我应该注意处理器的内核数,还是Windows内部进程管理?
请帮助我澄清这种情况,我真的想了解它在后台的工作方式,因为这将有助于选择正确的配置来运行这种类型的代码。
答案 0 :(得分:5)
Node.js在单个线程中运行您放入其中的JavaScript,但是它有更多线程来执行I / O和微任务队列的各种任务。在我撰写此答案时,Node.js将始终至少具有7个线程:4个用于libuv事件循环[1],4个用于运行V8的后台任务[2],以及1个用于调度V8的延迟后台任务
由于各种原因,您的数据库库,其他插件或Node.js核心中的杂项可能正在创建其他线程。
这显示为多核利用率,因为(简单来说)CPU将在核心周围传递线程。
作为return await
is completely unneeded的补充说明,您可以从异步函数返回诺言,由于诺言解析是一种平面映射操作,它们将被取消包装。
[1] libuv处理I / O,例如从文件读取,建立tcp套接字和调度计时器。
[2] V8后台任务包括运行垃圾收集器和优化代码。