异步获取循环

时间:2018-09-03 08:17:07

标签: javascript node.js mongodb

我有一个异步操作,正在获取项目数组:

Base.find({ creatorId: req.params.id })

该数组中的每个项目都有一个ID,我需要使用该ID来获取该项目的消息和用户。为此,我需要一个循环:

Base.find({ creatorId: req.params.id })
        .then(bases => {
            for (let base of bases) {
            }
        })

Bsae.find()将返回多个项目,因此会循环。节点中GET方法的末尾将必须返回一个类似于以下内容的数组:

bases: [
  {
   base: {info about base},
   users: 12,
   messages: 51
   },
   ...another base...,
   ...another base...
]

到目前为止,我无法在循环中使用多个Promises(.find方法),也无法在后续serialize().then()进行信息处理。我已经阅读了有关堆栈溢出的其他文章,其中他们建议使用async/await函数,但这只能让我执行两种方法之一(baseUser.find())。我不知道如何对Base.find()

最初返回的每个基数执行这些操作

编辑: 为了澄清起见,我需要调用以下函数: Base.find =>返回一个基数数组。 BaseUser.find() =>这需要处于循环中,因为我需要使用第一个find中的ID来findMessage.find() =>与基本用户相同,使用Base.find()中的ID提取消息。

EDIT2 : 我现在收到了一些数据,但由于无法从以下任何方式获取数据,因此对我来说几乎没有用处:

async function fetcher() {
    try {
        const bases = await Base.find({ creatorId: req.params.id });
        const baseUserPromises = bases.map(base =>
            BaseUser.find({ baseId: base._id })
        );
        return await Promise.all(baseUserPromises);
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: "Internal server error" });
    }
}
fetcher().then(data => console.log(data))

结果:

[ [ { created: 2018-09-03T14:05:39.968Z,
      acceptedMembership: true,
      isCreator: true,
      _id: 5b8d3fb3ccdfcc2e20540604,
      userId: 'tester1',
      baseId: 5b8d3fb3ccdfcc2e20540603},
    { created: 2018-09-03T14:05:43.357Z,
      acceptedMembership: false,
      isCreator: false,
      _id: 5b8d3fb7ccdfcc2e20540605,
      userId: 'tester2',
      baseId: 5b8d3fb3ccdfcc2e20540603},
    { created: 2018-09-03T14:05:44.797Z,
      acceptedMembership: false,
      isCreator: false,
      _id: 5b8d3fb8ccdfcc2e20540606,
      userId: 'tester3',
      baseId: 5b8d3fb3ccdfcc2e20540603 } ],
  [ { created: 2018-09-03T14:11:48.802Z,
      acceptedMembership: true,
      isCreator: true,
      _id: 5b8d4124e96ca00eb42df8c9,
      userId: 'tester1',
      baseId: 5b8d4124e96ca00eb42df8c8 } ] ]

Promise.all()返回的第一个数组具有已解决的Promises,然后Mongo的collection.find()也返回一个数组。因此,这是一个Promise数组,其中填充了两个find数组,并填充了find

的结果

2 个答案:

答案 0 :(得分:0)

根据我从您的问题中了解的内容,您想要获取基本数组并将其用于两个异步函数。您可以按照以下步骤进行操作。

const sampleFunc = async function(){
  try {
    const bases = await Base.find(YOUR_REQUIREMENT);
    const baseUsers = await BaseUser.find(YOUR_REQUIREMENT);
    const messages = await Message.find(YOUR_REQUIREMENT);
  } catch (error) {
    console.log(error);
  }
}

此方法必须有效。

答案 1 :(得分:0)

您尝试过使用Promise.all吗?

 try {
    const bases = await Base.find({ creatorId: req.params.id });
    const baseUserPromises = bases.map(b => BaseUser.find({}));
    const result = await Promise.all(baseUserPromises);
  } catch (e) {
    // TODO: handle errors
  } finally {
    // DO: something
  }

首先获取所需的所有数据,然后可以构建要返回的对象数组。

编辑 更新的代码

function getBasePromise(base) {
  return new Promise(async (resolve, reject) => {
    const users = await BaseUser.countDocuments({ baseId: base._id });
    resolve({
      base,
      users,
    });
  });  
}

async function fetcher() {
    try {
        const bases = await Base.find({ creatorId: req.params.id });
        const baseUserPromises = bases.map(base => getBasePromise(base));
        return await Promise.all(baseUserPromises);
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: "Internal server error" });
    }
}