【发布时间】:2020-08-02 15:06:56
【问题描述】:
我正在尝试运行我的函数,以便从 firebase cloud firestore 下载一些实时数据库数据更改。
问题是我的闭包 onSuccess 触发得早,闭包中的数组总是空的。
如何处理执行顺序,以便仅在 forEach() 之后成功执行闭包
在线阅读后,我想出了一些队列,但我不确定我是否正确使用。
在我的代码下面:
func getuserConfirmFriend(userLoggato: UserModel, onSuccess: @escaping([UserModel]) -> Void, onError: @escaping(_ errorMessage: String) -> Void, newPendingUser: @escaping(UserModel) -> Void, userRemoved: @escaping(UserModel) -> Void , listener: @escaping(_ listenerHandle: ListenerRegistration) -> Void){
let queue = OperationQueue()
let listenerRegistration = db.collection("user").document(userLoggato.userID).collection("confirmFriend").addSnapshotListener(includeMetadataChanges: true) { documentSnapshot, error in
var userConfirmFriendsArray = [UserModel]()
guard let snapshot = documentSnapshot else { return }
let operation1 = BlockOperation {
snapshot.documentChanges.forEach { (documentChange) in
switch documentChange.type {
case .added :
let dict = documentChange.document.data()
let name = dict["name"] as? String ?? "na name"
let surname = dict["surname"] as? String ?? "na name"
let email = dict["email"] as? String ?? "na name"
let userLevel = dict["adminLevel"] as? String ?? "unable to get admin level"
let idUser = dict["userID"] as? String ?? "no ID"
let position1 = dict["position"] as? String ?? "na preferance position"
let position2 = dict["position2"] as? String ?? "na preferance position"
let vote = dict["vote"] as? Int ?? 0
self.downloadImageForAdmin(userID: idUser) { (urlImage) in
let utente = UserModel(name: name, surname: surname, email: email, userID: idUser, adminLevel: userLevel, immagine: urlImage, position: position1, position2: position2, vote: vote)
newPendingUser(utente)
userConfirmFriendsArray.append(utente)
// onSuccess(userConfirmFriendsArray)
}
print("CONFIRM User Added")
case .modified :
//implements action (new escaping)
print("CONFIRM User Modified ")
case .removed :
print("CONFIRM User Removed")
let dict = documentChange.document.data()
let name = dict["name"] as? String ?? "na name"
let surname = dict["surname"] as? String ?? "na name"
let email = dict["email"] as? String ?? "na name"
let userLevel = dict["adminLevel"] as? String ?? "unable to get admin level"
let idUser = dict["userID"] as? String ?? "no ID"
let position1 = dict["position"] as? String ?? "na preferance position"
let position2 = dict["position2"] as? String ?? "na preferance position"
let vote = dict["vote"] as? Int ?? 0
self.downloadImageForAdmin(userID: idUser) { (urlImage) in
let utente = UserModel(name: name, surname: surname, email: email, userID: idUser, adminLevel: userLevel, immagine: urlImage, position: position1, position2: position2, vote: vote)
userRemoved(utente)
}
}
}
}
let operation2 = BlockOperation{
DispatchQueue.main.async {
onSuccess(userConfirmFriendsArray)
}
}
queue.addOperation(operation1)
queue.addOperation(operation2)
}
listener(listenerRegistration)
}
我的问题是 userConfirmFriend 总是空的,即使代码先执行 operation1 然后 2
对调度队列不太熟悉。
谢谢
【问题讨论】:
-
您需要获得熟悉调度队列。您的代码是异步的。如果您不知道这意味着什么,请找出答案;我在这里有一些关于它的文章:programmingios.net/what-asynchronous-means 要在继续调用完成处理程序之前完成循环的所有迭代,您需要一个 调度组。这已经在 Stack Overflow 上解释过很多很多次了。 (我提到“很多”吗?)请在再次询问之前搜索。谢谢。
标签: arrays swift multithreading firebase google-cloud-firestore