我正在使用Firestore一段时间,我想实现一个调用以从子集合中获取数据。
我必须创建一个异步调用,并且foreach()方法未等待调用并继续执行,但是它与for()方法一起使用。有人可以向我解释为什么for()等待而foreach()没有等待吗?
Foreach()-不起作用
export const FirebaseSearchUsers = async (search: string) => {
const end = search.replace(/.$/, c => String.fromCharCode(c.charCodeAt(0) + 1));
let users: UserDocument[] = [];
await firestore()
.collection(FirebaseConstraints.UserCollection)
.where('username', '>=', search)
.where('username', '<', end)
.limit(10)
.get()
.then(async x => {
x.forEach(async y => {
let userDocument: UserDocument = y.data() as UserDocument;
userDocument.houseInvites = [];
await y.ref
.collection(FirebaseConstraints.HouseInvitesCollection)
.get()
.then(x => x.forEach(x => userDocument.houseInvites.push(x.data() as HouseInviteDocument)));
users.push(userDocument);
});
});
return users;
};
For()-作品
export const FirebaseSearchUsers = async (search: string) => {
const end = search.replace(/.$/, c => String.fromCharCode(c.charCodeAt(0) + 1));
let users: UserDocument[] = [];
await firestore()
.collection(FirebaseConstraints.UserCollection)
.where('username', '>=', search)
.where('username', '<', end)
.limit(10)
.get()
.then(async x => {
for (let y of x.docs) {
let userDocument: UserDocument = y.data() as UserDocument;
userDocument.houseInvites = [];
await y.ref
.collection(FirebaseConstraints.HouseInvitesCollection)
.get()
.then(x => x.forEach(x => userDocument.houseInvites.push(x.data() as HouseInviteDocument)));
users.push(userDocument);
}
});
return users;
};
答案 0 :(得分:2)
Foreach期望同步回调;)
(第二条黄色备忘录)
您的版本不错,但受阻。 (您可以并行处理秒数请求以更快地获得结果)
编辑
要并行化,也许这应该有用;)
export const FirebaseSearchUsers = async (search: string) => {
const end = search.replace(/.$/, c => String.fromCharCode(c.charCodeAt(0) + 1));
// wrap this in try catch to handle errors ;)
const usersQuerySnapshot = await firestore()
.collection(FirebaseConstraints.UserCollection)
.where('username', '>=', search)
.where('username', '<', end)
.limit(10)
.get();
const futureUsers = usersQuerySnapshot.docs.map(async userSnapshot => {
const userDocument: UserDocument = userSnapshot.data() as UserDocument;
const houseInvitesSnapshots = await userSnapshot.ref
.collection(FirebaseConstraints.HouseInvitesCollection)
.get();
const houseInvites = houseInvitesSnapshots.docs.map(snapshot => snapshot.data() as HouseInviteDocument);
// or you can use the builtin method forEach of houseInvitesSnapshots and declare a "let" houseInvites array
// let houseInvites = [];
// houseInvitesSnapshots.forEach(snapshot => houseInvites.push(snapshot.data() as HouseInviteDocument));
// these 2 forms should works same (I did not test ;)
// Then, return a copy of your user document and fill its houseInvites property
return { ...userDocument, houseInvites};
})
const users = await Promise.all(futureUsers);
return users;
};