提问者:小点点

如何处理异步forEach,将结果传递到数据库,然后呈现完整的数据集


我想:

  1. 调用API资源
  2. 获取记录数组-[arr]
  3. 在[arr]上foreach并执行某些函数-对API的另一个aysnc调用
  4. 对于每个迭代,创建一个对象,该对象包含原始API调用的元素以及每个项的后续调用的元素
  5. 将生成的每个对象实例保存到Mongo
  6. 在所有必需的保存操作结束时,从Mongo调用完整的集合
  7. res.render该集合

我的代码如下所示:

  //First API call to get [arr]
  const results = await getlist();
  //Iterate over [arr] and perform a request on each item 
  _.forEach(results, async function (result) {

  //Seconday request for each item in [arr]
  const record = await item(result.id).fetch();

  //Combined doc from original result and secondary call for record
  let doc = new DocModel({
    item1: result.id,
    item2: record.something,
    
  });
  //Save doc
  const saveDoc = doc.save();

  });

//Call for all docs
const allItems = await DocModel.find();

 //Render all docs
 res.render(`aView`, {
   recordings: allItems,
 });

我面临的问题是,呈现在forEach完成/填充Mongo之前执行。

为了解决这个问题,我尝试将forEach块包装在一个promise中,然后。然后是res.render,但这似乎没有效果。

要确保所有函数调用在呈现发生之前都已完成,解决方案是什么?


共3个答案

匿名用户

您不能在foreach内部使用async await。相反,您需要使用for.。。of循环。

另一个最佳解决方案是使用promise.all

匿名用户

承诺。全部

await Promise.all(_.map(results,async result => {
   ... existing code
});

匿名用户

我在下面的代码中放置两个标记。我删除了_.foreach函数

mark1:使用普通for-loop执行此操作
mark2:在此处使用await

//First API call to get [arr]
const results = await getlist();

// ########## mark1 ########## : Use normal for-loop to do it
for (const result of results) {
    //Seconday request for each item in [arr]
    const record = await item(result.id).fetch();

    //Combined doc from original result and secondary call for record
    let doc = new DocModel({
        item1: result.id,
        item2: record.something,

    });
    // ########## mark2 ########## : use await here 
    //Save doc
    const saveDoc = await doc.save();
}

//Call for all docs
const allItems = await DocModel.find();

//Render all docs
res.render(`aView`, {
    recordings: allItems,
});

相关问题