Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 正在读取嵌套firebase函数中其他用户的快照_Javascript_Firebase_Firebase Realtime Database - Fatal编程技术网

Javascript 正在读取嵌套firebase函数中其他用户的快照

Javascript 正在读取嵌套firebase函数中其他用户的快照,javascript,firebase,firebase-realtime-database,Javascript,Firebase,Firebase Realtime Database,我正在尝试循环浏览我的数据库,其结构如下: 我想使用引用其他用户的RBUserID(RB:referenced By)键。我使用下面的代码循环浏览userID,并找到哪个userID与RBUserID匹配 function readOnceandFindRef() { refRead.once("value", function (snapshot) { snapshot.forEach(function (childSnapshot) { var

我正在尝试循环浏览我的数据库,其结构如下:

我想使用引用其他用户的RBUserID(RB:referenced By)键。我使用下面的代码循环浏览userID,并找到哪个userID与RBUserID匹配

function readOnceandFindRef() {
  refRead.once("value", function (snapshot) {
    snapshot.forEach(function (childSnapshot) {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();

      var RBUserID = childData.RBUserID;
      console.log(RBUserID);
      debugger; // 1
      refRead.child(RBUserID).once("value", function (snapshot) {
        if (snapshot.exists()) {
          console.log(snapshot.key);
          debugger; // 2
        }
        debugger; // 3
      });
    });
  });
}
forEach循环读取users和console.log(RBUserID)工作,但随后跳过

refRead.child(RBUserID).once("value", function (snapshot) {
并且直到forEach循环结束后才运行调试器2和调试器3。chrome调试器显示以下内容:

任何关于它跳过内部read函数的原因的帮助都是值得赞赏的,因为
once()
是异步的,并且在查询完成之前立即返回。您传递给它的回调在一段时间后被调用,而代码在它继续执行后立即被调用


请注意,
once()
还返回一个与快照对象解析的承诺,更常见的做法是使用该承诺而不是回调参数,以便更容易进行异步编程。

正如@Doug在回答中正确指出的那样,因为
once()
是一个异步操作,您可能需要调整函数
readOnceandFindRef
,以便同步检查所有值

解决方案之一是使用
for of
循环,而不是
forEach
循环

async function readOnceandFindRef() {
  const snapshots = await refRead.once("value");
  for (const snapshot of snapshots) {
    var childKey = snapshot.key;
    var childData = snapshot.val();

    var RBUserID = childData.RBUserID;
    console.log(RBUserID);
    debugger; // 1
    const childSnapshot = await refRead.child(RBUserID).once("value");
    if(childSnapshot.exists()){
      console.log(snapshot.key);
      debugger; // 2
    }
    debugger; // 3
  }
}
但是,在这种情况下,您将逐个检查每个用户id。 但是使用
Promise.all
的解决方案,您可以并行执行所有此类异步操作

解决方案2

async function readOnceandFindRef() {
  const snapshots = await refRead.once("value");
  
  // Following part allows us to execute all the asynchronous operations 
  // at once and still store their outcomes synchronously in the results array.
  const results = await Promise.all(snapshots.map(snapshot => {
    var childKey = snapshot.key;
      var childData = snapshot.val();
  
      var RBUserID = childData.RBUserID;
      console.log(RBUserID);
      debugger; // 1
      return refRead.child(RBUserID).once("value").then(snapshot => {
        const doesRefReadExist = false;
        if(childSnapshot.exists()){
          console.log(snapshot.key);
          doesRefReadExist = true;
        }
        return { rbUserID: RBUserID, doesRefReadExist}
      }) ;
  }))
}
results
数组看起来像:

[
  {
     rbUserID: RBUserID-1,
     doesRefReadExist: true/false
  },
  {
     rbUserID: RBUserID-2,
     doesRefReadExist: true/false
  },
.
.
.
]