所以我想使用这种效果:
useEffect(() => {
return db.collection('users').orderBy('lastName').onSnapshot(snap => {
const usersArray = []
snap.forEach( async doc => {
const user = doc.data()
if(user.manager) {
await Promise.all([
db.collection('users').doc(user.manager).get(),
db.collection('roles').doc(user.profile).get()
]).then(resp => {
const manager = resp[0].data()
const role = resp[1].data()
usersArray.push({
id: doc.id,
...user,
manager: `${manager.lastName} ${manager.name} ${manager.middleName}`,
role: role.profile
})
})
} else {
await db
.collection('roles')
.doc(user.profile)
.get().then(resp => {
const role = resp.data()
usersArray.push({
id: doc.id,
...user,
role: role.profile
})
})
}
usersArray.push({test: 'test'})
})
console.log(usersArray)
setAgents(usersArray)
})
}, [])
这里我要获取用户列表,然后我想为每个用户获取有关他们在系统中及其管理者角色的数据,并更新用户对象并推送到数组。之后,我要渲染它。但是现在,我总是得到空数组。在console.log
的{{1}}中,数据是正确的。
请帮助获取正确的代码
答案 0 :(得分:1)
这是因为代码的console.log
部分是在将任何数据实际写入数组之前同步执行的。 forEach
数组属性创建一个与主执行无关的非阻塞回调。如果要确保在执行snap
之前处理console.log
中的每个项目,我建议改用map
,则map具有一个唯一的属性,它实际上返回一个值(与foreach相反) )。在这种情况下,返回值将是回调承诺。您可以等待地图的结果,以确保所有项目都已写入数组,甚至最好在回调内部返回实际项目。
这是示例代码(为简单起见,我删除了我认为不需要的usersArray.push({test: 'test'})
)
useEffect(() => {
return db.collection('users').orderBy('lastName').onSnapshot(snap => {
const usersArrayPromise = snap.documents.map(doc => {
const user = doc.data();
if (user.manager) return Promise.all([
db.collection('users').doc(user.manager).get(),
db.collection('roles').doc(user.profile).get()
]).then(resp => {
const manager = resp[0].data();
const role = resp[1].data();
return {id: doc.id, ...user, manager: `${manager.lastName} ${manager.name} ${manager.middleName}`, role: role.profile};
});
return db.collection('roles')
.doc(user.profile)
.get().then(resp => {
const role = resp.data();
return {id: doc.id, ...user, role: role.profile}
})
});
Promise.all(usersArrayPromise).then(usersArray => {
console.log(usersArray)
setAgents(usersArray)
});
})
}, []);
请注意以下事实:firebase QuerySnapshot不是实际的数组,而是实现了forEach
属性之类的数组,如果要使用map,则可以执行snap.documents.map
。