使用 async/await 时,Firebase Cloud Firestore 查询返回 Promise { <pending> } 而不是 complete
这个问题 类似,但没有帮助。
目标是将 async/await 与 Firebase Cloud Firestore 查询一起使用,而不是 Firebase 文档 中的 then/catch Promise 代码。
但是,下面的函数在否定情况下成功拒绝,但返回
Promise { <pending> } 而不是 Cloud Firestore 文档。
async getUser(emailAddress) {
// Return null if @emailAddress blank.
if (!emailAddress) {
return null;
}
// Assume @db points to a Cloud Firestore database. Query only returns one doc.
let query = db.collection('users').where('emailAddress', '==', emailAddress);
try {
let querySnapshot = await query.get();
querySnapshot.forEach(function(doc) {
return doc.data();
});
} catch(e) {
console.log('Error getting user: ', e);
}
}
如果
emailAddress
不为 null 或未定义,则您的函数不会返回任何内容,因为
forEach()
返回 void。
由于
querySnapshot
中只有一个文档,您可以执行以下操作:
async getUser(emailAddress) {
// Return null if @emailAddress blank.
if (!emailAddress) {
return null;
}
// Assume @db points to a Cloud Firestore database. Query only returns one doc.
const query = db.collection('users').where('emailAddress', '==', emailAddress);
try {
const querySnapshot = await query.get();
return querySnapshot.docs[0].data();
} catch(e) {
console.log('Error getting user: ', e);
}
}
请注意,您的
getUser()
函数本身是异步的,因此您需要使用
then()
(或 async/await)在其返回的 Promise 得到满足时获取文档值。
const emailAddress = "[email protected]";
getUser(emailAddress).
then(userData => { ... })
您尝试从
forEach
返回,但
forEach
未返回任何内容,而是循环遍历元素并允许您修改它们。
您可以像这样修改代码:
async getUser(emailAddress) {
// Return null if @emailAddress blank.
if (!emailAddress) {
return null;
}
// Assume @db points to a Cloud Firestore database. Query only returns one doc.
let query = db.collection('users').where('emailAddress', '==', emailAddress);
try {
const results = [];
let querySnapshot = await query.get();
querySnapshot.forEach(function(doc) {
results.push(doc.data());
});
return results;
} catch(e) {
console.log('Error getting user: ', e);
}
}
有关 forEach 的更多信息:
forEach() executes the callback function once for each array element; unlike map() or reduce() it always returns the value undefined and is not chainable. The typical use case is to execute side effects at the end of a chain.
async
函数(例如您的函数)
始终
返回一个承诺。这是无法避免的。所有异步行为仍存在于函数中,并且调用者仍必须
await
或
then
才能获取承诺中的值。您不能使用 async/await 删除承诺并立即返回。
最重要的是,您的函数实际上不会返回任何文档。
forEach
中的返回实际上只是从您传递给
forEach
的内联 lambda 函数返回。该返回不会扩展到封闭的
getUser
函数。
如果您想有效地使用 async/await,该函数仍必须从其顶层返回一个值。并且调用者仍必须使用 await 或 then 从返回的承诺中获取值。