Firebase Cloud Firestore 查询在使用 async/await 时返回 Promise { <pending> } 而不是 fulfilled
Firebase Cloud Firestore query returning Promise { <pending> } instead of fulfilled when using async/await
类似但没有帮助。
目标是将 async/await 与 Firebase Cloud Firestore 查询一起使用,而不是 the Firebase documentation 中的 then/catch Promise 代码。
然而,下面的函数在否定的情况下成功拒绝,但 returns 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);
}
}
async
函数,例如你的函数,总是 return 一个承诺。这是无法避免的。所有异步行为仍然存在于函数中,调用者仍然必须 await
或 then
才能获得承诺中的值。您不能使用 async/await 删除承诺并立即 return。
最重要的是,您的函数实际上 return 没有任何文档。 forEach
中的 return 实际上只是 return 来自您传递给 forEach
的内联 lambda 函数。 return 没有扩展到封闭的 getUser
函数。
如果您想有效地使用 async/await,该函数仍然需要 return 从其顶层获取一个值。并且调用者仍然必须使用 await 或 then 从 returned promise 中获取值。
您正在尝试从 forEach
return,但是 forEach
没有 return 任何东西,而是遍历元素并允许您修改它们。
您可以像这样修改您的代码,例如:
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.
如果 emailAddress
不为 null 或未定义,则您的函数 returns 没有任何内容,因为 forEach()
returns 无效。
由于您在 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 it returns 时获取文档值满足了。
const emailAddress = "john@gmail.com";
getUser(emailAddress).
then(userData => { ... })
目标是将 async/await 与 Firebase Cloud Firestore 查询一起使用,而不是 the Firebase documentation 中的 then/catch Promise 代码。
然而,下面的函数在否定的情况下成功拒绝,但 returns 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);
}
}
async
函数,例如你的函数,总是 return 一个承诺。这是无法避免的。所有异步行为仍然存在于函数中,调用者仍然必须 await
或 then
才能获得承诺中的值。您不能使用 async/await 删除承诺并立即 return。
最重要的是,您的函数实际上 return 没有任何文档。 forEach
中的 return 实际上只是 return 来自您传递给 forEach
的内联 lambda 函数。 return 没有扩展到封闭的 getUser
函数。
如果您想有效地使用 async/await,该函数仍然需要 return 从其顶层获取一个值。并且调用者仍然必须使用 await 或 then 从 returned promise 中获取值。
您正在尝试从 forEach
return,但是 forEach
没有 return 任何东西,而是遍历元素并允许您修改它们。
您可以像这样修改您的代码,例如:
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.
如果 emailAddress
不为 null 或未定义,则您的函数 returns 没有任何内容,因为 forEach()
returns 无效。
由于您在 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 it returns 时获取文档值满足了。
const emailAddress = "john@gmail.com";
getUser(emailAddress).
then(userData => { ... })