【问题标题】:Wait for multiple Promises in Firebase Functions在 Firebase 函数中等待多个 Promise
【发布时间】:2019-01-15 21:30:17
【问题描述】:

我试图弄清楚如何在函数结束之前等待几个 Promise 被执行。

基本上,这是我尝试做的:

  • 如果用户删除了他/她的帐户,我想清理与他关联的所有数据
  • 可以删除直接数据
  • 如果用户是组的一部分,如果其他用户在该组中,则该组仍然存在;否则该组也将被删除

这是我目前尝试过的:

A) 主函数(启动第一级promise):

export function cleanUpAllData(user) {
  const userId = user.uid;
  const promises = [];
  promises.push(deleteCategoriesData(userId)); // this works fine
  promises.push(deleteUserAndGroupData(userId)); // this one has other promises which still run when Promise.all() is finished
  Promise.all(promises)
    .then(() => {
      return "ok"; // this works so far, but not all promises are resolved
    })
    .catch(errPromises => {
      console.log("an error occured during the processing of main promises");
      console.log(errPromises, errPromises.code);
      return "error";
    })
}

B) deleteUserAndGroupData 函数(另一个 Promise 工作正常):在用户数据中找到的每个组都启动另一个级别的 Promise,并触发第三级 Promise (deleteGroup) - 其余工作正常

function deleteUserAndGroupData(userId) {
  const promisesUserData = [];

  return admin.firestore().collection('users').doc(userId).collection('groups').get()
    .then(userGroups => {
        userGroups.forEach(userGroupData => {
            // delete group data
            promisesUserData.push(deleteGroups(userId, userGroupData.id)); // here are other promises that need to be resolved - somewhere is a problem              
            // delete all Groups in Users (subcollection)
            promisesUserData.push(deleteGroupInUser(userId, userGroupData.id)); // this works fine          
        });
        Promise.all(promisesUserData)
        .then(() => {
            admin.firestore().collection('users').doc(userId).delete()
                .then(() => {
                    return "user data deleted"; // works fine
                })
                .catch(() => {
                    console.log("an error occured during deleting of user");
                    return "error";
                });
        })
        .catch(errPromises => {
            console.log("an error occured during the processing of promisesUserData");
            console.log(errPromises, errPromises.code);
            return "error";
        })
    })
    .catch(errUserGroups => {
        console.log(errUserGroups, errUserGroups.code);
        return "no groups in User";
    });
}

C) deleteGroups 功能:删除组中的子集合(工作正常),然后如果没有其他用户则删除组(不起作用)

function deleteGroups(userId,groupId) {
  const promisesDeleteGroups = [];
  // delete groups subcollection data 
  promisesDeleteGroups.push(deleteGroupRole(userId, groupId));
  promisesDeleteGroups.push(deleteGroupUser(userId, groupId));

  return Promise.all(promisesDeleteGroups).then(() => {
    checkForOthers(groupId);
  }).catch(errDeleteGroupSubcollections => {
    console.log("an error occured during the processing of promisesDeleteGroups");
    console.log(errDeleteGroupSubcollections, errDeleteGroupSubcollections.code);
    return "error";
  });
}

D) checkForOthers 函数 - 检查子集合中是否有任何条目并开始删除组(但没有)

function checkForOthers(groupId) {
  return admin.firestore().collection('groups').doc(groupId).collection('users').get()
    .then(groupUsers => {
        return "other users exist - group should not be deleted";
    })
    .catch(errGroupUsers => {
        // console.log("no other group members - group can be deleted");
        // return "no other group members - group can be deleted";
        console.log(errGroupUsers, errGroupUsers.code);
        checkForInvitesAndDelete(groupId);
    });;
}

E) checkForInvitesAndDelete:首先我想删除另一个可能存在或可能不存在的子集合,如果另一个用户已被邀请到该组;那么它应该触发最后的组删除(这似乎不起作用)

function checkForInvitesAndDelete(groupId) {
  const promisesInvitesAndDelete = [];
  return admin.firestore().collection('groups').doc(groupId).collection('invitations').get()
    .then(groupInvitations => {
        console.log("delete open Group Invitations");
        groupInvitations.forEach(groupInvite => {
            promisesInvitesAndDelete.push(deleteGroupInvite(groupId, groupInvite.id));
        });
        Promise.all(promisesInvitesAndDelete)
            .then(() => {
                deleteGroup(groupId)
            })
            .catch(errPromisesInvitesAndDelete => {
                console.log("an error occured during the processing of deleting group invites");
                console.log(errPromisesInvitesAndDelete, errPromisesInvitesAndDelete.code);
                return "error";
            });
    })
    .catch(() => {
        console.log("no open invitations");
        deleteGroup(groupId);
    });
}

F) 删除组函数

function deleteGroup(groupId) {
  return admin.firestore().collection('groups').doc(groupId).delete();
}

我对编程比较陌生,尤其是 Firebase 函数,所以任何帮助都将不胜感激!

谢谢!

【问题讨论】:

    标签: firebase promise google-cloud-firestore google-cloud-functions


    【解决方案1】:

    我添加了“return”语句,这很有帮助,但这不是完整的答案。

    在 (D) 中,我认为如果我的集合没有数据,它会进入“捕获”阶段,但事实并非如此。所以,我需要在我的“then”阶段检查一个空的结果集。

    if (groupUsers.empty) {
      return checkForInvitesAndDelete(groupId);
    } else {
      return "other users exist - group should not be deleted";
    } 
    

    在没有打开邀请时与函数(E)相同。

    【讨论】:

      【解决方案2】:

      您没有在任何地方使用return 关键字,它应该在哪里。如果您执行async 任务,则必须以某种方式“return”。

      一些例子:

      示例A:在Promise.all(promises)之前添加return

      ...B:在Promise.all(promisesUserData)之前添加return

      ...C:在checkForOthers(groupId)之前添加return

      ... D:在checkForInvitesAndDelete(groupId)之前添加return

      ... E:在Promise.all(promisesInvitesAndDelete)deleteGroup(groupId)之前添加return

      【讨论】:

      • 异步函数不需要返回任何东西。
      • @DougStevenson 忘记return 来自普通function 的承诺就像忘记await 中的async function 承诺。
      • 但是你上面的陈述表明异步函数仍然必须返回一个承诺?
      猜你喜欢
      • 2020-11-09
      • 2017-01-15
      • 1970-01-01
      • 2019-03-31
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多