【问题标题】:Catching errors in async functions in an async function在异步函数中捕获异步函数中的错误
【发布时间】:2021-01-02 21:35:27
【问题描述】:

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

我想调用一个函数来更新多个数据库/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() 块中调用了拒绝)

【问题讨论】:

    标签: javascript angular firebase google-cloud-firestore


    【解决方案1】:

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

    如果您可以在.delete(或第二组)发生之前等待第一个.set 完成,您只需在当前代码上粘贴一些awaits:

    // 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);
    

    【讨论】:

      【解决方案2】:

      很简单,只需在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
        }
        // ...
      }
      

      【讨论】:

        猜你喜欢
        • 2019-11-26
        • 2017-10-23
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 2021-10-20
        • 1970-01-01
        • 2020-08-24
        • 2020-10-01
        相关资源
        最近更新 更多