我有两个集合,即用户和问题。
根据使用userId登录的用户,我从currQuestion
集合中检索users
值。
根据currQuestion
值,我需要从Firebase question
集合中检索Questions
文档。
我使用以下代码检索userId
rootRef.child("0").child("users")
.queryOrderedByChild("userId")
.queryEqualToValue("578ab1a0e9c2389b23a0e870")
.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
for child in snapshot.children {
self.currQuestion = child.value["currentQuestion"] as! Int
}
print("Current Question is \(self.currQuestion)")
//print(snapshot.value as! Array<AnyObject>)
}, withCancelBlock : { error in
print(error.description)
})
并检索问题
rootRef.child("0").child("questions")
.queryOrderedByChild("id")
.queryEqualToValue(currQuestion)
.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
for child in snapshot.children {
print(child.value["question"] as! String)
}
}, withCancelBlock: { error in
print(error.description)
})
但是上面的代码是异步执行的。我需要解决方案使这个同步或如何实现监听器,以便我可以在currQuestion
值更改后重新启动问题查询?
答案 0 :(得分:6)
编写您自己的方法,该方法将完成处理程序作为其参数,并等待该代码块完成。像这样:
func someMethod(completion: (Bool) -> ()){
rootRef.child("0").child("users")
.queryOrderedByChild("userId")
.queryEqualToValue("578ab1a0e9c2389b23a0e870")
.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
for child in snapshot.children {
self.currQuestion = child.value["currentQuestion"] as! Int
}
print("Current Question is \(self.currQuestion)")
completion(true)
//print(snapshot.value as! Array<AnyObject>)
}, withCancelBlock : { error in
print(error.description)
})
}
然后,只要你想调用那个函数,就像这样调用:
someMethod{ success in
if success{
//Here currValue is updated. Do what you want.
}
else{
//It is not updated and some error occurred. Do what you want.
}
}
完成处理程序通常用于等待一段代码完全执行。 P.S。只要他们不阻止主线程,异步请求就会通过添加完成处理程序来实现同步,就像上面显示的代码一样。
它只是等待您的currValue
首先更新(从服务器接收数据async
),然后当您拨打someMethod
时就像我一样显示,因为函数someMethod
的最后一个也是唯一的参数是一个闭包(又名尾随闭包),你可以跳过括号并调用它。 Here是关于闭包的好读物。并且由于封闭是类型(Bool) - &gt; (),您只需告诉someMethod
任务完成时的操作,例如我的代码中的completion(true)
,然后在调用时,您可以使用success
调用它(您可以使用任何你想要的词)将类型 Bool ,因为它被声明为这样,然后在函数调用中使用它。希望能帮助到你。 :)