同步嵌套的异步任务
Synchronize nested async task
我有嵌套的异步任务。下面的函数遵循此流程:loadEpisodes(加载剧集列表)-> 使用完成的数组循环遍历每个剧集,并为特定剧集加载评论(另一个异步任务)。
问题是:comletion(fullyEpisodes) 在完成评论加载任务之前执行。我尝试使用 Dispatch Group(第二个代码块),但它不起作用。
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)
})
}
实施调度组:
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)
})
})
}
当我尝试用 "print("something")" (不是新的异步任务)替换评论加载请求时,调度组正在工作。
在您的第二个示例中,(a) 将 group.leave()
移动到 load()
完成处理程序闭包中; (b) 完全删除 group.wait()
。
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)
})
})
}
或者,使用尾随闭包语法稍微清理一下并修复 completion
拼写:
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)
}
}
}
我有嵌套的异步任务。下面的函数遵循此流程:loadEpisodes(加载剧集列表)-> 使用完成的数组循环遍历每个剧集,并为特定剧集加载评论(另一个异步任务)。
问题是:comletion(fullyEpisodes) 在完成评论加载任务之前执行。我尝试使用 Dispatch Group(第二个代码块),但它不起作用。
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)
})
}
实施调度组:
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)
})
})
}
当我尝试用 "print("something")" (不是新的异步任务)替换评论加载请求时,调度组正在工作。
在您的第二个示例中,(a) 将 group.leave()
移动到 load()
完成处理程序闭包中; (b) 完全删除 group.wait()
。
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)
})
})
}
或者,使用尾随闭包语法稍微清理一下并修复 completion
拼写:
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)
}
}
}