是否有任何解决方案可以等待嵌套的 forEach 直到在 node.js 中使用 async/await 返回结果

Uma*_*mar 6 callback node.js async-await google-cloud-functions firebase-cloud-messaging

我正在研究 FCM,需要频道/房间中的所有成员的设备令牌来发送推送通知,并且每个成员都有多个设备,为此我需要两个 for 循环。

我正在将 async/await 与 firestore 查询一起使用,但它不会等待结果,而是在后台处理它并移至需要结果数据的下一条语句。

const notification = async (channelId) => {
    let tokens = []
    const members = await db.collection('channels/' + channelId + '/members').get();
    await members.forEach(async (member) => {
        const deviceTokens = await db.collection('users/' + member.id + '/devices').get();
        await deviceTokens.forEach(async (token) => {
            console.log(token.id);
            await tokens.push(token.data().token);
        })
    })
    console.log(tokens);
    return await sendPush(tokens); // calling other functions
}
Run Code Online (Sandbox Code Playgroud)

我希望输出是tokens = ['token1', 'token2', 'token3'],但实际输出是tokens = []

Est*_*ask 6

forEach不能与 一起有效地使用async..await。由于查询返回查询快照,因此应该迭代数组。无极链可以与系列来执行for..of或平行Promise.all和阵列map,如在解释相关的问题,例如:

const notification = async (channelId) => {
    let tokens = [];
    const members = await db.collection('channels/' + channelId + '/members').get();
    for (const member of members.docs) {
      const deviceTokens = await db.collection('users/' + member.id + '/devices').get();
      for (const deviceToken of deviceTokens.docs) {
        tokens.push(deviceToken.data().token);
      }
    }

    return await sendPush(tokens);
}
Run Code Online (Sandbox Code Playgroud)

await sendPush(...)只有在sendPush返回承诺时才能正常工作。