为什么javascript不等待forEach的and并执行下一行

为什么javascript不等待forEach的and并执行下一行,javascript,node.js,angular,reactjs,es6-promise,Javascript,Node.js,Angular,Reactjs,Es6 Promise,当我在nodejs中创建api并尝试将mongoose返回计数推送到新创建的数组时,它不会等待forEach并执行json.res()并给出null响应。当我使用 setTimeout()然后它会给出正确的结果 让newcategories=[]; 让服务=0; const categories=await Category.find({},'.\u id name'); categories.forEach(异步(类别)=>{ service=wait service.count({categ

当我在nodejs中创建api并尝试将mongoose返回计数推送到新创建的数组时,它不会等待forEach并执行json.res()并给出null响应。当我使用 setTimeout()然后它会给出正确的结果

让newcategories=[];
让服务=0;
const categories=await Category.find({},'.\u id name');
categories.forEach(异步(类别)=>{
service=wait service.count({category:category});
push({count:service});
log('newcategories为--',newcategories);
});  /* 在执行这个forEach时,它不是等待并执行res.json*/
console.log('result--',result);
log('out newcategories为--',newcategories);
res.json({状态:200,数据:newcategories});

您需要使用map而不是forEach来收集等待并等待它们完成。编辑:或者您可以使用
for..of
这非常简洁(谢谢其他ppl)

const categories=['a','b','c'];
函数getNextCategory(旧类别){
返回新承诺((解决)=>{
设置超时(()=>{
解析(String.fromCharCode(oldCategory.charCodeAt(0)+1));
}, 1000);
});
}
异步函数blah(){
const categoryPromises=categories.map(getNextCategory);
const nextCategories=wait Promise.all(类别promises);
console.log(nextCategories);
}
诸如此类;
异步函数blah2(){
const nextCategories=[];
for(类别的常量类别){
push(等待getNextCategory(category));
};
console.log(nextCategories);
}

blah2()因此,您遇到的问题是,
async
标记的函数将根据默认值返回一个承诺,但是
Array.prototype.forEach
方法不关心回调函数的结果类型,它只是执行一个操作

在你的
async
函数中,它将正确地
等待你的回答并填充你的新类别,但是
forEach
关于类别的循环将早已消失

您可以选择将语句转换为循环,也可以使用
map
然后
wait Promise.all(mapped)

for..的循环是这样的

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);
}));
地图版本如下所示

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);
}));

第二个版本之所以有效,是因为它只会在所有承诺完成后解析,并且映射将为每个类别返回一个潜在的未解析承诺

好吧,您不能等待forEach,但是回调函数被标记为
async
(因此它将自动返回一个
承诺
)。因此,
forEach
早在您的等待准备就绪之前就完成了。只需将
forEach
更改为
for let categories of categories
并在
for..of
块中等待即可……….非常感谢:)for(let categories of categories){service=wait service.count({category:categories});newcategories.push({u-id:category.{u-id,name:category.name,count:service}}}您可以使用
reduce
在系列中运行它:
categories.reduce(async(previous,category)=>{await-previous;service=await-service.count…},null);
..或者只做一个“普通的老版”
for..of
loop,如果你想做串行请求。是的,在这之前我不知道for..of为那工作,所以这很酷