Swift 在加载数据之前调用完成处理程序
在以下代码中从firebase加载数据之前,如何防止调用完成处理程序 我的问题: 在将任何用户追加到用户数组之前调用Completion。只有在Swift 在加载数据之前调用完成处理程序,swift,firebase-realtime-database,grand-central-dispatch,Swift,Firebase Realtime Database,Grand Central Dispatch,在以下代码中从firebase加载数据之前,如何防止调用完成处理程序 我的问题: 在将任何用户追加到用户数组之前调用Completion。只有在users实际添加了用户之后,我如何调用completion 我必须使用中央调度中心吗 如果你能像我5岁一样向我解释这一点,那么我就可以不再面对这个问题了 class func fetchFavorites(userId: String, completion: @escaping ([User]) -> Swift.Void) { let
users
实际添加了用户之后,我如何调用completion
我必须使用中央调度中心吗
如果你能像我5岁一样向我解释这一点,那么我就可以不再面对这个问题了
class func fetchFavorites(userId: String, completion: @escaping ([User]) -> Swift.Void) {
let userRef = Database.database().reference().child("users")
let favRef = Database.database().reference().child("favorites").child(userId)
favRef.observe(.value) { snap in
var users: [User] = []
for item in snap.children.allObjects as! [DataSnapshot] {
userRef.child(item.key).observeSingleEvent(of: .value) { snapshot in
if let dictionary = snapshot.value as? [String:Any] {
let newUser = User(dictionary: dictionary)
users.append(newUser)
}
}
}
completion(users)
}
}
您有两个嵌套的异步函数,即
favRef.observe
和userRef.child().observeSingleEvent(of:)
,因此问题是在外部闭包中调用completion
,然后更新用户的所有异步调用才能完成执行
您可以通过使用DispatchGroup
解决此问题,并且在所有异步方法调用完成循环中的执行后,只调用completion
。这可以通过将所有异步调用添加到调度组
,然后在组内调用完成
。通知
调用来实现
class func fetchFavorites(userId: String, completion: @escaping ([User]) -> Swift.Void) {
let userRef = Database.database().reference().child("users")
let favRef = Database.database().reference().child("favorites").child(userId)
let usersGroup = DispatchGroup()
favRef.observe(.value) { snap in
var users: [User] = []
for item in snap.children.allObjects as! [DataSnapshot] {
usersGroup.enter()
userRef.child(item.key).observeSingleEvent(of: .value) { snapshot in
if let dictionary = snapshot.value as? [String:Any] {
let newUser = User(dictionary: dictionary)
users.append(newUser)
}
usersGroup.leave()
}
}
usersGroup.notify(queue: DispatchQueue.global()){
completion(users)
}
}
}
您有两个嵌套的异步函数,即
favRef.observe
和userRef.child().observeSingleEvent(of:)
,因此问题是在外部闭包中调用completion
,然后更新用户的所有异步调用才能完成执行
您可以通过使用DispatchGroup
解决此问题,并且在所有异步方法调用完成循环中的执行后,只调用completion
。这可以通过将所有异步调用添加到调度组
,然后在组内调用完成
。通知
调用来实现
class func fetchFavorites(userId: String, completion: @escaping ([User]) -> Swift.Void) {
let userRef = Database.database().reference().child("users")
let favRef = Database.database().reference().child("favorites").child(userId)
let usersGroup = DispatchGroup()
favRef.observe(.value) { snap in
var users: [User] = []
for item in snap.children.allObjects as! [DataSnapshot] {
usersGroup.enter()
userRef.child(item.key).observeSingleEvent(of: .value) { snapshot in
if let dictionary = snapshot.value as? [String:Any] {
let newUser = User(dictionary: dictionary)
users.append(newUser)
}
usersGroup.leave()
}
}
usersGroup.notify(queue: DispatchQueue.global()){
completion(users)
}
}
}
您的
completion()。你能在代码中澄清一下吗?你的completion()
在favRef.observe(.value){}
上被异步调用,这没关系,但是userRef.child(item.key)。observeSingleEvent(of:.value){}
也是异步的,这是你的问题。谢谢你的回复,但我不确定我是否遵循了。你能用代码说明吗?