异步代码后在 firestore 函数触发器中返回 null?

Returning null in firestore function trigger after async code?

我无法理解如何正确结束 Firestore 触发器。从我从 and 中读到的内容来看,如果没有异步代码,您似乎只应该 return null 来结束函数,例如在不满足条件时快速结束。当我在下面的场景中 return null 时,它似乎工作正常。对于我正在做的事情,有没有更好的做法我错过了?

我需要记录我自己的自定义错误消息,这就是我需要捕获的原因。我知道我可以在此处 return Promise.all 而不是 try 块中的 null ,但这只是我的场景的 sudo 代码。

export const delacc = functions.auth.user().onDelete(async (user) => {

  const userUID = user.uid;
  try{
      await admin.firestore().collection("users").doc(userUID).delete();
      await admin.firestore().collection("spam").doc(userUID).delete();
      await admin.firestore().collection("photos").doc(userUID).delete();
      return null;
  }catch(error){
      functions.logger.error(error)
      return null
  }  

});

return null 没有硬性要求。事实上,异步函数总是 return 一个承诺,无论你在函数内部做什么。 returns 的承诺基于您在处理过程中等待的任何其他承诺的完成。即使您显式 return null,该函数实际上仍然只是 returning 一个立即用值 null 实现的承诺。它对最终结果没有影响,因为 Cloud Functions onDelete 触发器不以任何方式使用已实现的值。重要的是函数确实 return 是一个 promise,它指示 all 工作何时完成(并且,正如我所说,如果您正确使用 await,异步函数总是这样做在所有异步工作的函数内)。

当你使用async/await时,我建议程序员总是return一个promise,or null如果有没有异步工作。 null 有一种明确的方式告诉代码的 reader 您不希望 Cloud Functions 在完全终止函数之前等待任何异步工作。它还有助于满足 eslint 或 TypeScript 警告,这将向您建议您应该 return 一些东西。值本身并不重要——它是您与其他人就您的功能终止进行交流的内容。如果您与他人合作,代码的可读性很重要。

我要做的是使删除操作原子化——删除所有文档或 none 其中的文档——以及 return 由批处理 return 承诺,因为那里这个函数中没有执行任何其他任务(这让我觉得 returning null 不是必要的抽象)。如果批处理抛出错误,则向客户端抛出一个新的 HTTPS 错误(连同批处理错误),该错误 (a) 自动终止云功能,并且 (b) 向客户端提供批处理错误以供评估,具体取决于原因,可以保证重试或向最终用户发送错误消息。

export const delacc = functions.auth.user().onDelete(async (user) => {
    const userUID = user.uid;
    const db = admin.firestore();
    const batch = db.batch();

    try {
        batch.delete(db.collection("users").doc(userUID));
        batch.delete(db.collection("spam").doc(userUID));
        batch.delete(db.collection("photos").doc(userUID));
        const writeResult = await batch.commit();
        return writeResult;
    } catch(error) {
        functions.logger.error(error);
        throw new functions.https.HttpsError("unknown", "batch-error", error);
    }
});