在异步函数中捕获异步函数中的错误

时间:2021-01-02 21:35:27

标签: javascript angular firebase google-cloud-firestore

我不确定标题是否正确描述了我的问题。如果我错了,请纠正我:)

我想调用一个函数来更新多个数据库/Firebase 身份验证中的用户数据(然后该函数调用多个其他异步函数)。我想在调用 updateUserData() 的父函数中进行所有错误处理。我该怎么做?

这是我的代码:

async updateUserData(user: User) {
  // Update Email
  const currentUser = this.getCurrentUser();
  if(user.email && user.email != currentUser?.email)
    currentUser?.updateEmail(user.email)
  
  // Update Display Name
  if(user.displayName && user.displayName != currentUser?.displayName) 
    currentUser?.updateProfile({displayName: user.displayName})

  // Update User DB
  this.firestore
    .collection('users')
    .doc(user.uid)
    .set(user, { merge: true })

  // Update Public User DB
  const publicUserDBRef = this.firestore.collection('public-users').doc(user.uid);
  if(user.displayName && !user.settings.isPrivate) {
    publicUserDBRef
      .set({ uid: user.uid, displayName: user.displayName }, { merge: true })
  } else {
    publicUserDBRef
      .delete()
  }
}

我尝试使用 try-catch 块,将 .catch( error => { throw new Error(error.code) }) 添加到 updateUserData() 中的所有异步函数,使用 return new Promise( (resolve, reject) => {...}resolve() 在最后被调用在更新公共用户数据库后,在每个 .catch() 块中调用拒绝)

2 个答案:

答案 0 :(得分:1)

.set.delete 返回承诺,但您没有对这些承诺做任何事情。所以无论是这个函数还是调用这个函数的任何函数都不会等待它们完成。这也意味着 try/catch 无法捕获它们抛出的任何异步错误。

如果您可以在 .set(或第二组)发生之前等待第一个 .delete 完成,您只需要在当前代码中添加一些 await :

// Update User DB
await this.firestore
  .collection("users")
  .doc(user.uid)
  .set(user, { merge: true });

// Update Public User DB
const publicUserDBRef = this.firestore.collection("public-users").doc(user.uid);
if (user.displayName && !user.settings.isPrivate) {
  await publicUserDBRef.set(
    { uid: user.uid, displayName: user.displayName },
    { merge: true }
  );
} else {
  await publicUserDBRef.delete();
}

如果您希望两者同时发生,那么我建议您创建一系列承诺,然后对它们执行 Promise.all,然后返回或等待该承诺:

const promises = [];
// Update User DB
promises.push(
  this.firestore.collection("users").doc(user.uid).set(user, { merge: true })
);

// Update Public User DB
const publicUserDBRef = this.firestore.collection("public-users").doc(user.uid);
if (user.displayName && !user.settings.isPrivate) {
  promises.push(
    publicUserDBRef.set(
      { uid: user.uid, displayName: user.displayName },
      { merge: true }
    )
  );
} else {
  promises.push(publicUserDBRef.delete());
}

return Promise.all(promises);

答案 1 :(得分:0)

很简单,只需在 await-ed 函数周围添加 try catch:

async function parentFunction() {
  // Here was created user
  try {
    await updateUserData(user);
  } catch (e) {
    console.log(`e is ${e}`);
    // Some handling of the error
  }
  // ...
}