【问题标题】:How to reload data after all Firebase calls finished?所有 Firebase 调用完成后如何重新加载数据?
【发布时间】:2017-07-25 15:31:20
【问题描述】:

我正在使用 Firebase (Swift) 读取用户所属的组 id 列表,然后循环遍历这些 id 以获取有关组的更多信息。类似的东西(伪代码):

// List the names of all Mary's groups
var ref = new Firebase("https://docs-examples.firebaseio.com/web/org");
// fetch a list of Mary's groups
ref.child("users/mchen/groups").on('child_added', function(snapshot) {
  // for each group, fetch the name and print it
  String groupKey = snapshot.key();
  ref.child("groups/" + groupKey + "/name").once('value', function(snapshot) {
    System.out.println("Mary is a member of this group: " + snapshot.val());
  });
});

我怎么知道所有 Firebase observeSingleEvent 都已执行完毕,以便我可以在我的集合视图中重新加载数据。

编辑:

经过更多研究,这看起来与question 非常相似。我可以使用dispatch_groupBolts framework

编辑2:

感谢@appzYourLife 的回答。我也能够使用RxSwift 解决它。我只是用观察者包装了 Firebase 调用并将它们保存在一个数组中,然后调用

Observable.zip(observables, { _ in }).subscribe(onCompleted: {
       self.contentView.collection.reloadData() // do something here
}) 

【问题讨论】:

  • 你的意思是如何处理 Firebase 的异步特性?使用回调还是调度队列?
  • 您的代码看起来像是JavaJavaScript 的混合体。您确定要在Swift 中寻找答案吗?
  • @appzYourLife 是的

标签: ios swift firebase firebase-realtime-database


【解决方案1】:

如果您想在所有 Firebase 调用完成时收到通知,您可以使用此代码

let ref = FIRDatabase.database().reference()
ref.child("users/mchen/groups").observeSingleEvent(of: .value, with: { snapshot in
    let groupKeys = snapshot.children.flatMap { $0 as? FIRDataSnapshot }.map { $0.key }

    // This group will keep track of the number of blocks still pending 
    let group = DispatchGroup()

    for groupKey in groupKeys {
        group.enter()
        ref.child("groups").child(groupKey).child("name").observeSingleEvent(of: .value, with: { snapshot in
            print("Mary is a member of this group: \(snapshot.value)")
            group.leave()
        })
    }

    // We ask to be notified when every block left the group
    group.notify(queue: .main) {
        print("All callbacks are completed")
    }
})

它是如何工作的?

涉及到 4 个主要指令。

  1. 首先我们创建一个组DispatchGroup()。该值将跟踪待处理块的数量。

    let group = DispatchGroup()
    
  2. 然后开始一个新的异步调用之前,我们告诉组有一个新的待处理块。

    group.enter()
    
  3. 在回调闭包中,我们告诉组一个块已经完成了它的工作。

    group.leave()
    
  4. 当组中的块数确实变为时,我们告诉块运行闭包。

    group.notify(queue: .main) {
        print("All callbacks are completed")
    }
    

【讨论】:

  • 哇,不知道是否存在。
  • 您能否提供另一种解决方案,让我在多个 alamofire 调用完成后运行我的代码?
【解决方案2】:

您拥有组列表,因此您可以将计数存储在一个 Int 对象中。让我们说 totalCount。

然后拿另一个对象。 让我们说计数器。

然后在每个完成处理程序中。 打印语句后

ref.child("groups/" + groupKey + "/name").once('value', function(snapshot) 
{
            System.out.println("Mary is a member of this group: " + snapshot.val());

            if counter == count
            {
                  collectionView.reload();
            }
            else
            {
                  counter += 1;
            }
});

【讨论】:

    猜你喜欢
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多