这是简单的节点路由,在其中调用异步api
。
在循环后,需要return data
。但是它正在返回空白对象。
try {
const array = ["brunch", "lunch", "crunch"]
const data = {}
array.map(async(d) => {
const venue = await Venue.find({ "category": { "$in": [d] }})
data[d] = venue
})
return data
} catch(err) {
throw err
}
请帮助我实现这一目标
答案 0 :(得分:4)
有一种更好的方法可以通过MongoDB获得所需的结果,而无需循环,请使用聚合框架,在该框架中,您可以运行以下使用 $facet
的管道作为
try {
const array = ["brunch", "lunch", "crunch"]
const facet = array.reduce((acc, cur) => {
acc[cur] = [{ "$match": { "category": cur } }]
return acc
}, {})
const pipeline = [
{ "$match": { "category": { "$in": array } } },
{ "$facet": facet }
]
const results = await Venue.aggregate(pipeline).exec()
const data = results[0]
return data
} catch(err) {
throw err
}
您还可以按类别键和 $push
每组文档对文档进行分组,然后将其转换为 $replaceRoot
}中的文档键。 strong>和 $arrayToObject
try {
const array = ["brunch", "lunch", "crunch"]
const pipeline = [
{ "$match": { "category": { "$in": array } } },
{ "$group": {
"_id": "$category",
"data": { "$push": "$$ROOT" }
} },
{ "$group": {
"_id": null,
"venues": {
"$push": {
"k": "$_id",
"v": "$data"
}
}
} },
{ "$replaceRoot": {
"newRoot": { "$arrayToObject": "$venues" }
} }
]
const results = await Venue.aggregate(pipeline).exec()
const data = results[0]
return data
} catch(err) {
throw err
}
答案 1 :(得分:2)
尽管@chridam方法非常独特,而且可能更有效,以防您想陷入循环。
有两种方法。您希望所有操作都可以并行或串行运行。
如果 parallel ,则必须使用Promise.all
。
try {
const array = ["brunch", "lunch", "crunch"]
const data = {}
await Promise.all(array.map(async(d) => {
data[d] = await Venue.find({ "category": { "$in": [d] }})
}))
return data
} catch(err) {
throw err
}
如果是系列,则必须使用简单的for
循环。
array.map(async(d) => {})
使内部数据库调用异步并且不等待操作。正常的for
循环将是同步的。
try {
const array = ["brunch", "lunch", "crunch"]
const data = {}
for (d of array) {
data[d] = await Venue.find({ "category": { "$in": [d] }})
}
return data
} catch(err) {
throw err
}
答案 2 :(得分:0)
问题是您使用async-await
的方式。它位于Array.prototype.map
内,该函数使.map
函数异步,因此主线程从不等待循环完成并前进到下一条语句,并返回data
,它就是{}
。 / p>
try {
const array = ["brunch", "lunch", "crunch"]
const data = {};
// here's the issue async is callback function to map, due to which never waited for map function to finished.
array.map( async(d) => {
const venue = await Venue.find({ "category": { "$in": [d] }})
data[d] = venue;
});
return data;
} catch(err) {
throw err
}
将代码更改为此:
(async function () {
try {
const array = ["brunch", "lunch", "crunch"]
const data = {};
array.map( d => {
const venue = await Venue.find({ "category": { "$in": [d] }})
data[d] = venue;
});
return data;
}
catch(err) {
throw err
}
})();
您所做的与此类似
function main () {
return new Promise ( resolve => {
setTimeout( () => {
console.log("First");
resolve(true);
},5000 );
});
}
(async function () {
await main();
console.log("Second")
})();
console.log("Third");
// Third
// First
// Second