This question already has answers here:
Wait until swift for loop with asynchronous network requests finishes executing
(8个答案)
去年关闭。
我想通过DispatchQueue.global()。async和DispatchQueue.main.async将异步任务用于我的应用程序,但是它不起作用。
我想从Firebase获取数据,然后制作List并将其传递给闭包。但是在下面的代码中,首先调用的计时完成是然后调用posts.append。
我想先完成for循环,然后再完成。有人可以给我任何想法吗?
(8个答案)
去年关闭。
我想通过DispatchQueue.global()。async和DispatchQueue.main.async将异步任务用于我的应用程序,但是它不起作用。
我想从Firebase获取数据,然后制作List并将其传递给闭包。但是在下面的代码中,首先调用的计时完成是然后调用posts.append。
func retrieveData(completion: @escaping ([Post]) -> Void) {
var posts: [Post] = []
let postsColRef = db.collection("posts").order(by: "createdAt").limit(to: 3)
postsColRef.getDocuments() { (querySnapshot, error) in
if let error = error {
print("Document data: \(error)")
} else {
DispatchQueue.global().async {
for document in querySnapshot!.documents {
let data = document.data()
let userId = data["userId"] as? String
let postImage = data["postImageURL"] as? String
let createdAt = data["createdAt"] as? String
let docRef = db.collection("users").document(userId!)
docRef.getDocument() { (document, error) in
if let document = document, document.exists {
let data = document.data()!
let userName = data["userName"] as? String
let post = Post(
userId: userId!,
userName: userName!,
postImageURL: postImage!,
createdAt: createdAt!
)
print("When append called")
posts.append(post)
}
}
}
DispatchQueue.main.async {
print("When completion called")
print(posts)
completion(posts)
}
}
}
}
}
我想先完成for循环,然后再完成。有人可以给我任何想法吗?
最佳答案
我只是找到了这个问题(Wait until swift for loop with asynchronous network requests finishes executing)并尝试了下面的代码,它可以正常工作。对每个检查过这个问题的人都感到抱歉。从下一次开始,我将首先搜索现有问题。谢谢。
func retrieveData(completion: @escaping ([Post]) -> Void) {
var posts: [Post] = []
let postsColRef = db.collection("posts").order(by: "createdAt").limit(to: 3)
let group = DispatchGroup()
postsColRef.getDocuments() { (querySnapshot, error) in
if let error = error {
print("Document data: \(error)")
} else {
for document in querySnapshot!.documents {
group.enter()
let data = document.data()
let userId = data["userId"] as? String
let postImage = data["postImageURL"] as? String
let createdAt = data["createdAt"] as? String
//投稿に紐づくユーザーデータを取得して合わせてpostArrayに挿入
let docRef = db.collection("users").document(userId!)
docRef.getDocument() { (document, error) in
if let document = document, document.exists {
let data = document.data()!
let userName = data["userName"] as? String
let post = Post(
userId: userId!,
userName: userName!,
postImageURL: postImage!,
createdAt: createdAt!
)
posts.append(post)
group.leave()
}
}
}
group.notify(queue: .main) {
print(posts)
completion(posts)
}
}
}
}
关于swift - 想使用DispatchQueue.global()。async和main.async,但效果不佳,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54559014/
10-11 06:15