I have nested async tasks. The function below following this flow: loadEpisodes(load a list of episodes) -> use a array from completion to loop through each episode one and load comments ( one more async task ) for specific episode.
The problem is: comletion(fullyEpisodes) excuted before finishing comments load task. I tried to use Dispatch Group (second code block) but it's not working.
func loadComments(comletion: @escaping ([Episode]) -> Void){
loadEpisodes(completion: {
episodes in
var fullyEpisodes = [Episode]()
for episode in episodes {
WebService().load(resource: episode.comment, comletion: {
comments in
if let comments = comments {
let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
fullyEpisodes.append(_episode)
print("done")
}
})
}
comletion(fullyEpisodes)
})
}
Implemented Dispatch Group:
func loadComments(comletion: @escaping ([Episode]) -> Void){
loadEpisodes(completion: {
episodes in
var fullyEpisodes = [Episode]()
let group = DispatchGroup()
for episode in episodes {
group.enter()
WebService().load(resource: episode.comment, comletion: {
comments in
if let comments = comments {
let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
fullyEpisodes.append(_episode)
print("done")
}
})
group.leave()
}
group.wait()
group.notify(queue: .main, execute: {
comletion(fullyEpisodes)
})
})
}
When I try to replace the comment load request by "print("something")" (not a new async task), Dispatch group is working.
In your second example, (a) move group.leave()
into the load()
completion handler closure; and (b) remove the group.wait()
altogether.
func loadComments(comletion: @escaping ([Episode]) -> Void){
loadEpisodes(completion: {
episodes in
var fullyEpisodes = [Episode]()
let group = DispatchGroup()
for episode in episodes {
group.enter()
WebService().load(resource: episode.comment, comletion: {
comments in
if let comments = comments {
let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
fullyEpisodes.append(_episode)
print("done")
}
group.leave()
})
// group.leave()
}
//group.wait()
group.notify(queue: .main, execute: {
comletion(fullyEpisodes)
})
})
}
or, cleaning that up a bit with trailing closure syntax and fixing completion
spelling:
func loadComments(completion: @escaping ([Episode]) -> Void) {
loadEpisodes { episodes in
var fullyEpisodes = [Episode]()
let group = DispatchGroup()
for episode in episodes {
group.enter()
WebService().load(resource: episode.comment) { comments in
if let comments = comments {
let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
fullyEpisodes.append(_episode)
}
group.leave()
}
}
group.notify(queue: .main) {
completion(fullyEpisodes)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With