gpt4 book ai didi

javascript - 在 Node.js 中链接异步函数的正确方法是什么?

转载 作者:行者123 更新时间:2023-11-30 13:23:09 26 4
gpt4 key购买 nike

我有一个有趣的案例,我需要使用 Mongoose 在 MongoDB 中执行一些查询,但响应在我完成所有查询之前返回。

我有两种文档类型,列表和项目。在一个特定的调用中,我需要获取特定用户的所有列表,然后遍历每个列表并获取所有项目并将它们附加到适当的列表,然后再返回。

List.find({'user_id': req.params.user_id}, function(err, docs){
if (!err) {
if (docs) {

var results = [];

_und.each(docs, function(value, key) {

var list = value.toObject();
list.items = [];

Item.find({'list_id': value._id}, function(err, docs) {
if (!err) {
_und.each(docs, function(value, key) { list.items.push(value.toObject()); });
results.push(list);
}
else {
console.log(err);
}
});
});

res.send(results);

(_und 是我导入 underscore.js 的方式)

显然问题出在回调上,由于存在多个循环,我无法在回调内返回。

也许在这种情况下,我需要提前获取计数并在每次迭代时检查它以决定何时返回结果。但这看起来并不优雅。

最佳答案

代码解决方案

首先,问题出在代码上。您在 Item.find 查询完成之前发送结果。你可以很容易地解决这个问题

var count = docs.length + 1;
next()
_und.each(docs, function(value, key) {

var list = value.toObject();
list.items = [];

Item.find({
'list_id': value._id
}, function(err, docs) {
if (!err) {
_und.each(docs, function(value, key) {
list.items.push(value.toObject());
});
// push asynchronous
results.push(list);
next()
}
else {
console.log(err);
}
});
});

function next() {
--count === 0 && finish()
}

function finish() {
res.send(results)
}​

最简单的方法是引用计数,你默认计数到文档的数量。然后,每次你完成获取一个项目时,你调用 next 并将计数减一。

一旦您获得所有元素,您的数量应该为零。请注意,我们执行 .length + 1 并立即调用 next。这可以防止没有文档的情况,否则文档将不执行任何操作。

数据库解决方案

最好的解决办法是正确使用mongo。你不应该在你的代码中做有效的连接,它非常缓慢且效率低下。您应该有一个嵌套文档并使您的列表非规范化。

所以 list.items = [Item, Item, ...]

此外,避免使用 mongoose,它效率低下,请使用 native mongo 驱动程序。

关于javascript - 在 Node.js 中链接异步函数的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9510453/

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