如何在使用 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;
};
这是我当前代码的[简化版]:
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;
};