Max*_*aev 2 dispatch grand-central-dispatch dispatch-async swift
我对编程很新,所以我有一个简单的问题.实际上,写作可以帮助我更快地识别问题.
无论如何,我有一个多个异步调用的应用程序,它们嵌套如下:
InstagramUnoficialAPI.shared.getUserId(from: username, success: { (userId) in
InstagramUnoficialAPI.shared.fetchRecentMedia(from: userId, success: { (data) in
InstagramUnoficialAPI.shared.parseMediaJSON(from: data, success: { (media) in
guard let items = media.items else { return }
self.sortMediaToCategories(media: items, success: {
print("success")
// Error Handlers
Run Code Online (Sandbox Code Playgroud)
看起来很可怕,但那不是重点.一旦我开始工作,我将调查Promise Kit.
我需要sortMediaToCategories等待完成然后重新加载我的集合视图.但是,在sortMediaToCategories我有另一个嵌套函数,它也是异步并且具有for循环.
func sortMediaToCategories(media items: [StoryData.Items],
success: @escaping (() -> Swift.Void),
failure: @escaping (() -> Swift.Void)) {
let group = DispatchGroup()
group.enter()
for item in items {
if item.media_type == 1 {
guard let url = URL(string: (item.image_versions2?.candidates?.first!.url)!) else {return}
mediaToStorageDistribution(withImageUrl: url,
videoUrl: nil,
mediaType: .jpg,
takenAt: item.taken_at,
success: { group.notify(queue: .global(), execute: {
self.collectionView.reloadData()
group.leave()
}) },
failure: { print("error") })
//....
Run Code Online (Sandbox Code Playgroud)
我无法承担集合视图每次显然重新加载,所以我需要等待循环完成然后重新加载.
我正在尝试使用Dispatch Groups,但正在努力解决它.你能帮帮我吗?任何简单的例子和任何建议将非常感激.
您面临的问题是一个常见的问题:拥有多个异步任务并等待所有任务完成.
有一些解决方案.最简单的是利用DispatchGroup:
func loadUrls(urls: [URL], completion: @escaping ()->()) {
let grp = DispatchGroup()
urls.forEach { (url) in
grp.enter()
URLSession.shared.dataTask(with: url) { data, response, error in
// handle error
// handle response
grp.leave()
}.resume()
}
grp.notify(queue: DispatchQueue.main) {
completion()
}
}
Run Code Online (Sandbox Code Playgroud)
该函数loadUrls是异步的,并且期望一个URL数组作为输入,并且在完成所有任务时将调用一个完成处理程序.这将通过所示的完成DispatchGroup.
最关键的是,要确保grp.enter()将被调用之前调用任务,grp.leave当任务被称为已经完成.enter并且leave应该是平衡的.
grp.notify最后注册一个闭包,当DispatchGroup grp平衡时(即,它的内部计数器达到零),将在指定的调度队列(此处为:main)上调用该闭包.
但是,这个解决方案有一些注意事项:
对于所有这些警告,有很好的解决方案应该使用合适的第三方库来实现.例如,您可以将任务提交给某种"执行者",该"执行者"控制并发运行的任务数(与OperationQueue和async Operations匹配).
许多"Promise"或"Future"库简化了错误处理,并且只需一个函数调用就可以帮助您解决这些问题.
| 归档时间: |
|
| 查看次数: |
1465 次 |
| 最近记录: |