如何在foreach循环中等待admin.auth().getuser()方法?

v6ylcynt  于 2021-09-23  发布在  Java
关注(0)|答案(3)|浏览(338)

我试图迭代一系列评论,需要抓住评论人的评论 uid 对于每一条评论。我是javascript的初学者,需要以下用例的帮助:
我要去拿那个 uid 对于每个注解,然后运行 .getUser() 方法,该方法将返回与用户电子邮件地址关联的用户电子邮件地址 uid . 自从 .getUser() 返回一个承诺(方法引用链接),我需要在这个循环的某个地方等待。如何做到这一点?这是一个好方法吗?
(注意:我的最终目标是最终将电子邮件地址附加到 to 房地产 msg 对象,然后我将在其中发送电子邮件通知。)
注解的示例数据:

[
  {
    id: 1,
    uid: 'RGaBbiui'
  },
  {
    id: 2,
    uid: 'ladfasdflal'
  },
  {
    id: 3,
    uid: 'RGaBbiui'
  },
  {
    id: 4,
    uid: 'RGaBbiui'
  },
  {
    id: 5,
    uid: 'ladfasdflal'
  },
  {
    id: 6,
    uid: 'ladfasdflal'
  }
]

云函数示例:

export const sendCommentNotification = functions.firestore
  .document('users/{uid}/posts/{postId}/comments/{commentId}')
  .onCreate(async (snapshot, context) => {
    try {

  const commentsQuery = await admin
    .firestore()
    .collection(
      `users/${context.params.uid}/posts/${context.params.postId}/comments`
    )
    .get()

  const commentsArr = []

  commentsQuery.forEach((documentSnapshot) =>
    commentsArr.push(documentSnapshot.data())
  )

  const commentsArrUids = new Set(commentsArr.map((c) => c.uid))
  console.log(commentsArrUids)

  const emailAddresses = []
  commentsArrUids.forEach((uid) =>
    emailAddresses.push(admin.auth().getUser(uid))  // how to use await here?
  )

      ...

      const msg = {
        to: //TO DO..put email addresses here..
        ...
kpbpu008

kpbpu0081#

你不能使用 await 在一个 forEach 环你可以用 await 在一个 for-loop 但它们不会像在中那样同时运行 Promise.all() .
您可以使用promise.all()同时等待所有承诺:
返回的值将按照传递的承诺的顺序,而不管完成顺序如何。

const emailAddresses = []
commentsArrUids.forEach((uid) => {
  emailAddresses.push(admin.auth().getUser(uid))
})
const data = await Promise.all(emailAddresses)

数据将是userrecord的数组。
然后你可以使用 .map() 方法获取所有电子邮件的数组。

const emails = data.map((user) => user.email)

代码可以这样编写以使其更容易:

const commentsDocs = await admin.firestore().collection(`users/${context.params.uid}/posts/${context.params.postId}/comments`).get()

const userIds = commentsDocs.docs.map(comment => comment.userId)
const usersReq = userIds.map(u => admin.auth().getUser(u.uid))
const emails = (await Promise.all(usersReq))).map((user) => user.email)
vfhzx4xs

vfhzx4xs2#

改为使用for循环。

for (let i = 0; i < commentsArrUids.length; i++) {
  let user = await new Promise((resolve, reject) => {
    admin.auth().getUser(commentsArrUids[i]).then((user) => {
      resolve(user);
    });
  };
  emailAddresses.push(user);
}
vmpqdwk3

vmpqdwk33#

我将用替换foreach for of 承诺是一系列的。另外,我重写了一些代码,因为它们是多余的。

export const sendCommentNotification = functions.firestore
  .document("users/{uid}/posts/{postId}/comments/{commentId}")
  .onCreate(async (snapshot, context) => {
    try {
      const comments = await admin
        .firestore()
        .collection(
          `users/${context.params.uid}/posts/${context.params.postId}/comments`
        )
        .get();

      const uids = new Set();

      for (const comment of comments) {
        uids.add(comment.data().uid);
      }

      const emailAddresses = [];

      for (const uid of uids) {
        const res = await admin.auth().getUser(uid);
        emailAddresses.push(res);
      }
    } catch (err) {
      console.log(err);
    }
  });

相关问题