使用DispatchGroup,DispatchQueue和DispatchSemaphore按顺序执行for循环的Swift 4asynchronous调用

我想按顺序在swift中运行for循环,DispatchGroup将它们放在一起,所以我想使用DispatchQueue和DispatchSemaphore来实现我的目标。 我没有使我的计划工作,我怎么能强迫他们一个一个地等待和运行?

let dispatchGroup = DispatchGroup() let dispatchQueue = DispatchQueue(label: "taskQueue") let dispatchSemaphore = DispatchSemaphore(value: 1) for c in self.categories { dispatchSemaphore.wait() dispatchQueue.async(group: dispatchGroup) { if let id = c.categoryId { dispatchGroup.enter() self.downloadProductsByCategory(categoryId: id) { success, data in if success, let products = data { self.products.append(products) } dispatchSemaphore.signal() dispatchGroup.leave() } } } } dispatchGroup.notify(queue: dispatchQueue) { self.refreshOrderTable { _ in self.productCollectionView.reloadData() NVActivityIndicatorPresenter.sharedInstance.stopAnimating() } } 

感谢Palle ,这里是我的最终代码:

 let dispatchGroup = DispatchGroup() let dispatchQueue = DispatchQueue(label: "taskQueue") let dispatchSemaphore = DispatchSemaphore(value: 0) dispatchQueue.async { for c in self.categories { if let id = c.categoryId { dispatchGroup.enter() self.downloadProductsByCategory(categoryId: id) { success, data in if success, let products = data { self.products.append(products) } dispatchSemaphore.signal() dispatchGroup.leave() } dispatchSemaphore.wait() } } } dispatchGroup.notify(queue: dispatchQueue) { DispatchQueue.main.async { self.refreshOrderTable { _ in self.productCollectionView.reloadData() } } } 

您可以将整个循环放在一个块中,而不是只将下载function放在一个块中:

 dispatchQueue.async { for c in self.categories { if let id = c.categoryId { self.downloadProductsByCategory(categoryId: id) { success, data in if success, let products = data { self.products.append(products) } dispatchSemaphore.signal() } dispatchSemaphore.wait() } } } 

您可以使用flatMap来展开您的产品ID来简化您的代码:

 for id in self.categories.flatMap({$0.categoryId}) { ... }