如何在使用 onSnapshot 回调时让调用 firebase.firestore.set 的异步 React 函数等待?

How does one get an async React function calling firebase.firestore.set to wait whilst using an onSnapshot callback?

这是我当前代码的[简化版]:

export const setTimestamp = async () => {
    console.log("START")
    let result = null;
    const dbRef = await firestore.collection("collectionName").doc("docName");
    const unsub = await dbRef.onSnapshot(snap => {
        result = snap.data();
        console.log("ACTUAL END", result);
    });
    await dbRef.set({ serverTime: firebase.firestore.FieldValue.serverTimestamp() });
    unsub();
    console.log("FUNCTION END", result);
    return result;
};

FUNCTION END 当前在 ACTUAL END 之前记录,而我需要相反的方式。有任何想法吗?除了使用 onSnapshot 之外,还有其他选择吗?

感谢您的阅读。

嗯,onSnapshot 是一个 event,returns 是一个 Promise 订阅。但该事件将在订阅后触发。如果你想确保事件被触发,你需要另一个 Promise 来处理这个场景:

const res = await new Promise( async resolve=> {
const unsub = await dbRef.onSnapshot(snap => {
        result = snap.data();
        
        console.log("ACTUAL END", result);
        resolve({result,unsub});
    });
});

await dbRef.set({ serverTime: firebase.firestore.FieldValue.serverTimestamp() });
res.unsub();
console.log("FUNCTION END", res.result);
return res.result;

@Eldar 的回答是正确的,但我后来发现并更喜欢这种方法:

import { v4 as UUID } from "uuid";

export const setTimestamp = async () => {
    let result = null;
    const dbRef = firestore.collection("collectionName").doc(UUID());
    await bdRef.set({ serverTime: firebase.firestore.FieldValue.serverTimestamp() })
        .catch(error => console.log("ERROR", error));
    await dbRef.get()
        .then(value => result = value.data())
        .catch(error => console.log("ERROR", error));
    return result;
};