标题不言自明,我正在研究从模型数组中调用数据库函数的两种方法来处理
这是我的
for(const x in arr ) {
await insertIntoDB(x);
}
但是有人告诉我,这是处理它们的异步,而且性能更好,速度更快
const promises = [];
for(const x of arr ) {
promises.push( insertIntoDB() );
}
await Promise.all(promises);
或
await Promise.all(async arr.map(async x => insertIntoDB(x)));
我知道 js 不执行真正的并行操作,但它确实同时执行,所以调用 await wwithin al oop 与等待直到结束真的有什么区别吗?它们会按顺序处理还是同时处理以节省时间?
请查看以下答案:await Promise.all() 和 multiple await 之间有什么区别?.
for...of
,您将按顺序执行承诺,而如果您使用Promise.all
,您将并行运行它们,并且您将获得Promise.all
的快速失败能力,这将停止如果你的任何承诺失败了。
但是,在您使用
insertIntoDB
的示例中,我认为您可以通过在数据库中使用批量或批量插入,然后将这种并行性委托给 DBMS 并仅处理 Node.js 上的响应(可能作为一个承诺),选择这两种方法中的任何一种都意味着您将多次访问数据库以获得可以在一批中完成的事情。
有一个区别:没有
await
,即使数据库API仍在处理较早的请求,它也会收到新请求。然后,它取决于数据库引擎处理并发请求的能力。一些引擎可能只在当前请求完成后才考虑下一个请求,这意味着在客户端几乎没有任何好处:客户端没有对 promise 创建进行排队,但数据库仍在对请求进行排队。尽管所有的承诺都是一次性创建的,但解决承诺之间的时间将类似于 await
变体中发生的情况。
当数据库引擎 do 以并发方式执行操作时,不使用
await
可能会有所收获。也可能是这些并发操作会使数据库引擎使用大量资源(CPU 负载、内存),并且在某些时候可能仍然会减慢速度。
所以,这完全取决于非 JavaScript 部分(数据库引擎)如何处理多个请求。
你是对的,在 JavaScript 方面,两种解决方案都没有并发性。 可以提供良好的并发性是数据库 API 的非 JavaScript 部分。
有趣的问题。
循环专家:
循环缺点:
好奇为什么不这样做以使其更纯净和可重复使用:
const promises = arr.map(x => insertIntoDB(x))
// can debug each promise singly before waiting for them all
Promise.allSettled(promises).then(resp=> {
// do something with resp
})
还很好奇为什么您一次可以在一个帖子中发送多行以节省多次访问服务器时将一行插入到数据库中。
你可以看看这个 javascript playground 你可以通过图形演示了解 eventloop 行为