Firebase 函数:有没有办法异步迭代多个集合



在编写 API 时,我想收集一组对象并提取它们的每个属性。一个属性是每个对象中的一个集合。但是,<QuerySnapshot>似乎不支持异步迭代。

伪代码(使用 TypeScript(:

let objects = [];
const objectSnapshot = await admin.firestore().collection('object').get();
objectSnapshot.forEach(async (objectDoc) => {
    let values = [];
    const valueSnapshot = await admin.firestore().collection('object').doc(objectDoc.id).collection('value').get();
    valueSnapshot.forEach((valueDoc) => {
        values.push(valueDoc.data());
    });
    objects.push(values);
});
return objects;

以下代码不等待填充objects,并且不返回任何内容。

有什么建议吗?

问题是 forEach 本身不会同步运行,因此您需要在对象有机会填充之前返回它们。

您有几种选择来解决这个问题,在您的情况下,我建议您返回一系列承诺并等待它们完成再返回。像这样:

const objectSnapshot = await admin.firestore().collection('object').get();
// Creates an array of promises that can be awaited later
// You can use the docs property which is an array, and then you can use map on it
const promises = objectSnapshot.docs.map(async (objectDoc) => {
    // This will execute in parallel but will create a promise and add it to promises
    const valueSnapshot = await admin.firestore().collection('object').doc(objectDoc.id).collection('value').get();
    return valueSnapshot.docs.map((valueDoc) => valueDoc.data());
});
// Wait for all promises created before returning
return await Promise.all(promises);

您在这里犯的错误是,您传递给 forEach 的回调不应标记为异步。 所有异步函数都会立即返回一个承诺,当函数中所有其他等待的异步工作完成时,该承诺将解析。 这意味着forEach将迅速完成所有这些承诺,而无需等待它们解决。 迭代完成后,每个回调中的异步工作将完成。 这不是您想要用于Each的方式。

如果要对每个文档快照执行一些异步工作,并收集所有异步工作的结果,则应改为在 objectSnapshot.docs 中迭代文档数组。 然后,您可以对每个文档执行进一步的异步工作。 对于 JavaScript,使用数组的 map() 函数将文档快照数组转换为 promise 数组。 然后,您可以在该承诺数组上使用Promise.all()来等待所有工作完成。

最新更新