我正在为一个项目构建一个原始应用程序, 人们可以添加视图和删除条目,为此我正在使用nodejs,js和fireabse。 我有一个Firestore数据库结构:
entries:
--entry id
--entry data
users:
--user id
--user email (query)
-- my entries (collection)
-- entries id
--entry id
现在我要显示所有用户条目, 所以我创建了这个module.exports函数:
module.exports = {
//get all the users entries from database with passed in uid ('/dashboard')
getUserEntries: async uid => {
//get all his entries docs id from "myEntries" collection in an, array
const usersEntriesId = await db
.collection("users")
.doc(uid)
.collection("myEntries")
.get()
.then(entries => {
return entries.docs.map(entry => entry.data().entry);
})
.catch(err => console.log(err));
console.log(usersEntriesId); //works fine, logs array with ids
const userEntriesDocs = usersEntriesId.map(async id => {
const entry = await db
.collection("entries")
.doc(id)
.get()
.then(entry => {
return entry.data();
});
console.log("hello:", entry); //works fine returns logs entry data
return entry;
});
console.log("hello1: ", userEntriesDocs); //doesnt work i get "hello1: [ Promise { <pending> },
// Promise { <pending> },
//Promise { <pending> } ]"
//i got three entries, that's why i get 3 times "Promise { <pending> }"
}
};
那我该如何解决呢?
谢谢
答案 0 :(得分:3)
好吧,async
函数将返回Promise
,说明它们是如何工作的。如果没有.map
,则可以对该函数进行await
或将其与Promise
和.then()
一起用作任意.catch
。但是由于存在Promise
数组,因此您需要Promise.all
等待所有问题解决。
const userEntriesDocs = await Promise.all(usersEntriesId.map(async id => {
....
);
当心:与.allSettled
不同,.all()
将在随后的Promise
中任何一个失败时立即失败。因此,如果出于任何原因想要从成功的请求中获取数据,则需要更复杂的逻辑。
或者,您也可以手动循环:
const userEntriesDocs = [];
for(const docPromise of userEntriesId.map(.....)) {
userEntriesDocs.push(await docPromise);
}
但是对我来说await Promise.all[...]
更具可读性。
我还要强调指出,这里有很多Promises(请求已经发送)。如果您尝试在循环内 发送请求,例如
const userEntriesDocs = [];
for(const id of userEntriesId) {
userEntriesDocs.push(await db
.collection("entries")
.doc(id)
.get()
.then(entry => {
return entry.data();
})
);
}
您会发现请求严格按照一对一进行,而不是并行进行。这将需要更多时间来处理列表。