我在我的应用中使用Firebase,它通过大量用户查询并获取所需的特定数据,但是当它开始查询时 - 其余功能也继续运行,而不仅仅是查询,所以我可以不知道什么时候结束。
例如,在此代码中:
ref.observeEventType(.ChildAdded, withBlock: { snapshot in
let user = snapshot.value!.objectForKey("User")
let name = (user!["Name"])! as! String
print("name")
})
print("done")
假设Firebase数据库中有3个用户 - 打印的代码为:
done
nameuser1
nameuser2
nameuser3
(或done
将位于名称用户之间,取决于您的互联网连接 - 但它不会是最后一个)
答案 0 :(得分:1)
Firebase回调块是异步的,而打印行是同步的。这意味着只要从其底层API调用接收到数据,该块就会运行,而块外的“print”(和其他)行将继续按顺序运行。
这就是在回调块运行之前运行打印行的原因。
答案 1 :(得分:1)
您可以使用调度组,但只有在您必须的情况下才能使用,并且您不应该在主线程上执行此操作。
它看起来像这样:
let group = dispatch_group_create()
dispatch_group_enter(group)
ref.observeEventType(.ChildAdded, withBlock: { snapshot in
let user = snapshot.value!.objectForKey("User")
let name = (user!["Name"])! as! String
print("name")
dispatch_group_leave(group)
})
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
//will reach here only after group_leave is called
print("done")
答案 2 :(得分:1)
"问题"您的体验是由于函数observeEventType()
是异步的。因此,在实际检索到值之前,它会将控制权返回给调用者。使用这样的异步回调并传递一个函数,每次从firebase中检索一个值时都会调用该函数...
针对Swift 3进行了更新
func getDataFromFirebase(callback: @escaping (_ user: String, _ name: String)->Void){
ref.observeEvent(of: .childAdded, with:{(snapshot)-> Void in
let user = snapshot.value!.objectForKey("User") as! String
let name = (user!["Name"])! as! String
callback(user, name)
})
}
并像这样调用函数......
getDataFromFirebase(callback: {(user, name)-> Void in
print("got a user: \(user) and a name: \(name)")
})
这将打印用户和每个检索到的孩子的名称
答案 3 :(得分:0)
让我们从分析您的代码开始:
打印功能是同步的,
结果:无法强制asyc func作为同步工作。
这只是一种错误的做法
关于编译器如何编译代码:
首先,他将触发observeEventType函数,而不是传递执行其他东西(仅仅因为它是异步并且需要时间来完成执行)。
我建议你按照自己想要的方式完成这项工作,就是在viewDidLoad()函数中准备好你需要的所有数据(把它们放在变量中),而不仅仅是在私有函数中使用这些变量。