我正在使用Firebase实时数据库,并希望收集我可以访问的所有“笔记”-即。我被列为“作者”或受邀“成员”的地方。
我目前正在使用下面的代码来获取我可以访问的所有“笔记”。
return new Promise( (resolve, reject) => {
try{
let notes = []
//Get notes where I am author : uid = my user uid
database.ref('notes')
.orderByChild("access/author")
.equalTo(`${uid}`)
.on('value', (snapshot) => {
snapshot.forEach( (childSnapshot) => {
const note = {
id: childSnapshot.key,
...childSnapshot.val()
}
notes.push(note)
})
})
//Get notes where I am member
database.ref('notes')
.orderByChild(`access/members/${uid}`)
.equalTo(true)
.on('value', (snapshot) => {
snapshot.forEach( (data) => {
const note2 = {
id: data.key,
...data.val()
}
notes.push(note2)
})
})
//Return all notes
resolve(notes)
} catch(e) {}
})
该代码不起作用。结果数组不包含我被列为“成员”的注释。我怀疑原因是数据库调用是同步的-在返回所有注释的数组之前,它们不等待完成。
在解析数组之前,如何确保已获取所有注释?
亲切的问候/ K
答案 0 :(得分:1)
您实际上在这里处理了两个承诺,这是您的代码无法正常工作的原因之一。承诺只是围绕异步动作的上下文包装。您有两个不相关的同步操作(您的两个数据库调用),因此您希望将它们分别包装。
首先将代码拆分为单独的promise,然后将您的resolve语句移至数据库调用的“ on”方法中,这样它就不会在数据库调用完成之前得到处理:
const promise1 = new Promise( (resolve, reject) => {
let notes = []
//Get notes where I am author : uid = my user uid
database.ref('notes')
.orderByChild("access/author")
.equalTo(`${uid}`)
.on('value', (snapshot) => {
snapshot.forEach( (childSnapshot) => {
const note = {
id: childSnapshot.key,
...childSnapshot.val()
}
notes.push(note)
})
})
resolve(notes);
});
const promise2 = new Promise( (resolve, reject) => {
try{
let notes = [];
//Get notes where I am member
database.ref('notes')
.orderByChild(`access/members/${uid}`)
.equalTo(true)
.on('value', (snapshot) => {
snapshot.forEach( (data) => {
const note2 = {
id: data.key,
...data.val()
}
notes.push(note2)
})
resolve(notes);
});
})
然后,您真正想要的是解析从通话中获得的价值。意思是说,当这个诺言得到解决时,它就会收集价值。
现在将您的诺言放在一个数组中,并使用Promise.all等待这两个诺言发生。
Promise.all([
promise1,
promise2,
]).then(twoNotesArrays => { //[ [notesFromPromise1], [notesFromPromise2] ]
console.log(notes[0].concat(notes[1])); //[all notes]
});