当我在nodejs中创建我的api并尝试将mongoose返回计数推送到新创建的数组时,它不等待forEach并执行json.res()并给出null响应。我用的时候 setTimeout()然后它会给出正确的结果。
let newcategories = [];
let service = 0;
const categories = await Category.find({}, '_id name');
categories.forEach(async (category) => {
service = await Service.count({category: category});
newcategories.push({ count:service });
console.log('newcategories is -- ', newcategories);
}); /* while executing this forEach it's not wait and execute res.json..*/
console.log('result --- ',result);
console.log('out newcategories is -- ', newcategories);
res.json({status: 200, data: newcategories});
答案 0 :(得分:2)
您需要使用map而不是foreEach来收集等待并等待它们完成。编辑:或者您可以使用非常整洁的for..of
(感谢其他人)!
const categories = ['a', 'b', 'c'];
function getNextCategory(oldCategory) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(String.fromCharCode(oldCategory.charCodeAt(0)+1));
}, 1000);
});
}
async function blah() {
const categoryWaits = categories.map(async (category) => {
return await getNextCategory(category);
});
const nextCategories = await Promise.all(categoryWaits);
console.log(nextCategories);
}
blah();
async function blah2() {
const nextCategories = [];
for (category of categories) {
nextCategories.push(await getNextCategory(category));
};
console.log(nextCategories);
}
blah2();

答案 1 :(得分:0)
所以你遇到的问题是async
标记的函数将默认返回一个promise,但是Array.prototype.forEach
方法并不关心你的回调函数的结果类型,它只是执行一个动作。
在async
功能中,它会正确地await
您的回复并填写您的新类别,但类别上的forEach
循环将会消失。
您可以选择将语句转换为for .. of
循环,也可以使用map
然后使用await Promise.all( mapped )
for..of循环就像这样
for (let category of categories) {
service = await Service.count({category: category});
newcategories.push({ count:service });
console.log('newcategories is -- ', newcategories);
}
地图版本看起来像这样
await Promise.all( categories.map(async (category) => {
service = await Service.count({category: category});
newcategories.push({ count:service });
console.log('newcategories is -- ', newcategories);
}));
第二个版本的确有效,因为Promise.all只有在所有承诺完成后才会解决,并且地图将为每个类别返回一个可能未解决的承诺