gpt4 book ai didi

javascript - mongoDB 插入和处理.nextTick

转载 作者:行者123 更新时间:2023-11-30 17:01:04 28 4
gpt4 key购买 nike

我有一个 50k 条目的列表,我正在输入我的数据库。

var tickets = [new Ticket(), new Ticket(), ...]; // 50k of them
tickets.forEach(function (t, ind){
console.log(ind+1 + '/' + tickets.length);
Ticket.findOneAndUpdate({id: t.id}, t, {upsert: true}, function (err, doc){
if (err){
console.log(err);
} else {
console.log('inserted');
}
});
});

而不是预期的交错

1 / 50000
inserted
2 / 50000
inserted

我正在获取所有索引,然后是所有插入的确认

1 / 50000
2 / 50000
...
50000 / 50000
inserted
inserted
...
inserted

我认为 process.nextTick 发生了一些事情。几千条记录后速度明显下降。

有谁知道如何获得高效的交错?

最佳答案

Instead of the expected interleaving

这只是同步 I/O 的预期行为。

请记住,这些操作都是异步的,这是 node.js 的关键思想。代码的作用是这样的:

for each item in the list, 
'start a function' // <-- this will immediately look at the next item
output a number (happens immediately)
do some long-running operation over the network with connection pooling
and batching. When done,
call a callback that says 'inserted'

现在,代码将启动大量这些函数,这些函数依次向数据库发送请求。所有这一切都将在第一个请求甚至到达数据库之前很久就发生。很可能操作系统甚至懒得在你到达之前实际发送第一个 TCP 数据包,比如票 5 或 10 左右。

根据您的评论回答问题:不,请求将相对较快地发送出去(这取决于操作系统),但结果不会到达您的单线程 javascript 代码在您的循环尚未完成 50k 条目的排队之前。这是因为 forEach 是您当前正在运行的一段代码,并且在它运行时进入的所有事件只会在它完成后才被处理 - 如果您使用 setTimeout,您会观察到同样的情况(function() { console.log("inserted... not") }, 0) 而不是实际的数据库调用,因为 setTimeout 也是一个异步事件。

要使您的代码完全异步,您的数据源应该是某种提供数据的(异步)迭代器,而不是大量的项目。

关于javascript - mongoDB 插入和处理.nextTick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28844354/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com