Firebase实时数据库-等待多个查询完成

时间:2019-08-31 15:11:07

标签: javascript firebase firebase-realtime-database

我正在使用Firebase实时数据库,并希望收集我可以访问的所有“笔记”-即。我被列为“作者”或受邀“成员”的地方。

我的数据库结构如下图所示。 Database structure

我目前正在使用下面的代码来获取我可以访问的所有“笔记”。

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

1 个答案:

答案 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]
});