在Firebase雲端函數中,可以安全地非同步更新文件而無需等待即可返回嗎?
P粉043432210
2023-08-17 14:53:58
<p>在我的Firebase Cloud Function檔案中,我有以下的本機函數,它在傳回一些屬性之前執行了一個文件擷取和更新操作。 </p>
<pre class="brush:php;toolbar:false;">async function getRandomDocLessThanOperator(seed) {
try {
const db = admin.firestore();
const snapshot = await db.collection("users").where("random", "<=", seed)
.limit(1)
.get();
if (snapshot.empty) {
return null; // 呼叫者然後嘗試大於操作符
}
const doc = snapshot.docs[0];
doc.ref.update({"random": seed}); // 使用新的種子更新
return doc.get("uid");
} catch (error) {
throw new Error(error);
}
}</pre>
<p>這個函數工作正常,但我擔心在返回之前嘗試非同步更新文件。然而,在測試中,文件從未沒有更新過。但是,這個函數在更新完成之前是否有可能逾時? </p>
<p>無論如何,為了解決這個問題,我嘗試使用<code>await</code>來等待更新:</p>
<pre class="brush:php;toolbar:false;">const doc = snapshot.docs[0];
await doc.ref.update({"random": seed});
return doc.get("uid");</pre>
<p>然而,當我這樣做時,函數傳回了預期的字串,但沒有更新文件。 </p>
<ol>
<li>為什麼在更新作業前加上<code>await</code>會阻止更新? </li>
<li>不等待更新並像第一個範例那樣非同步執行是否安全? </li>
</ol><p><br /></p>
不清楚為什麼您的更新沒有起作用(也許您可以使用更多的日誌記錄來清楚地了解運行時發生了什麼)。但是我可以肯定地說,在使用Cloud Functions時,您必須返回一個在所有非同步工作完成後解決的承諾(或者等待遇到的每個承諾),否則函數可能在工作完成之前被關閉。這是開發人員常犯的錯誤。
不,這是不「安全」的,因為您無法保證非同步程式碼在函數終止後是否會繼續運作。您必須返回一個只在所有非同步工作完成後解決的承諾。
請閱讀有關此的文件。