Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.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
Ios Firebase:等待多个查询完成_Ios_Swift_Firebase - Fatal编程技术网

Ios Firebase:等待多个查询完成

Ios Firebase:等待多个查询完成,ios,swift,firebase,Ios,Swift,Firebase,我有多个对不同Firebase数据库位置的引用,它们都会获取一些数据。在继续下一步处理数据之前,我需要收集所有数据。代码如下: for ref in baseRefs { ref.queryOrdered(byChild: "datetime").queryLimited(toFirst: 4).observeSingleEvent(of: .value, with: { (postRefs) in for postRef in postRefs.children

我有多个对不同Firebase数据库位置的引用,它们都会获取一些数据。在继续下一步处理数据之前,我需要收集所有数据。代码如下:

for ref in baseRefs {
     ref.queryOrdered(byChild: "datetime").queryLimited(toFirst: 4).observeSingleEvent(of: .value, with: { (postRefs) in
          for postRef in postRefs.children {
               let snapshotValue = ((postRef as! DataSnapshot).value) as! [String: AnyObject]
               let dummyPost = Post(key: (postRef as! DataSnapshot).key, dummyTextCount: snapshotValue["textcount"] as! Int, datetime: snapshotValue["datetime"] as! Int)
               self.postsHeap.enqueue(dummyPost)
          }
     })
}
我希望堆包含从这些查询获取的所有帖子,然后再将它们显示在表视图中(因为时间戳排序)。是否有一种方法可以在继续之前等待上述多个查询完成


编辑:由于我需要从Firebase的不同节点获取数据,我不能只进行一次查询调用。

您可以利用
DispatchGroup
等待其他查询完成

稍微修剪一下代码:


实现这一点的方法有很多,但Firebase的不良做法是以一种需要多个观察者在不同数据库位置获取一个目的所需数据的方式来构造数据

你提到帖子,所以我认为你在创建某种提要

因此,与从数据库的不同部分获取所有帖子并在客户端上对它们进行组合/排序不同,每个用户都将有一个feed节点,当保存帖子时,您还将该帖子的id保存在users feed节点中,那么您的查询只是用户feed节点上的一个观察者,该节点已经拥有您所需的一切

此外,我可以看到您按“日期时间”排序,您是否知道在Firebase中,ID是按时间排序的,因此如果需要,您可以按其他子项排序,然后按orderByKey排序并限制到最后4个,然后您可以获取最近的4篇文章,同时还可以查询其他子项

您可以使用多路径更新或云函数在数据库中复制(非规范化)数据。如果您来自SQL,这可能会感觉很奇怪,但在Firebase中这是正常的


是一个firebase博客,提供有关正确结构和数据非规范化的更多信息。

既然您知道有多少个引用,并且您只想在处理最后一个引用时对UI进行排序和更新,那么简单的..if。。语句以查看是否已返回最后一个引用。大概是这样的:

let lastRefIndex = baseRefs.count - 1 //the index of the last ref
for (index, ref) in baseRefs.enumerated { //index tracks which ref we are on
     ref.queryOrdered(byChild: "datetime").queryLimited(toFirst: 4)
        .observeSingleEvent(of: .value, with: { (postRefs) in
          for postRef in postRefs.children {
               let snapshotValue = ...
               let dummyPost = ...
               self.postsHeap.enqueue(dummyPost)
          }

          //the following code will execute once for each ref as the data becomes
          //  valid. So index will only equal the lastRefIndex when all of the
          //  data has been returned.
          if index == lastRefIndex { 
             self.postsHeap.sort()
             updateUI
          }
     })
}

我在代码中使用它,但我总是使用
DispatchQueue.main.async{…}
。使用你写的东西有什么好处?你在哪部分使用它?代表整个代码;它可以并行调度调用,并将
qos
定义为
。userInitiated
为这些调用提供高优先级(我也使用
。userInteractive
),同时不占用主线程。从您发布的代码中,您只有一个Firebase调用,并且不清楚在哪里进行排序。
let lastRefIndex = baseRefs.count - 1 //the index of the last ref
for (index, ref) in baseRefs.enumerated { //index tracks which ref we are on
     ref.queryOrdered(byChild: "datetime").queryLimited(toFirst: 4)
        .observeSingleEvent(of: .value, with: { (postRefs) in
          for postRef in postRefs.children {
               let snapshotValue = ...
               let dummyPost = ...
               self.postsHeap.enqueue(dummyPost)
          }

          //the following code will execute once for each ref as the data becomes
          //  valid. So index will only equal the lastRefIndex when all of the
          //  data has been returned.
          if index == lastRefIndex { 
             self.postsHeap.sort()
             updateUI
          }
     })
}