在对API进行异步,递归调用时,如何使用GCD时我遇到了问题。
以下是三种包含相同逻辑的相似方法之一,仅适用于不同的数据和API端点。如果没有下一页请求,则该方法应完成,然后下一个方法应开始。
我如何确保在fetchItems2
完成后调用fetchItems1
,并在fetchItems3
之后调用fetchItems2
?
private func fetchItems1(completion: @escaping (Error?) -> Void) {
var _items = [Item]()
func handleReceivedItemsPage(_ page: PagingObject<Item>, _completion: ((Error?) -> Void)?) {
let newItems = page.items!
_tracks.append(contentsOf: newTracks)
if page.canMakeNextRequest {
page.getNext(success: { nextPage in
handleReceivedItemsPage(nextPage)
}) { nextError in
_completion?(nextError)
}
} else {
// Finished, next method can now start
self.items = _items
_completion?(nil)
}
}
API.getSavedItems(success: { page in
handleReceivedItemsPage(page, _completion: completion)
}, failure: completion)
}
private func fetchItems2(completion: @escaping (Error?) -> Void)) { ... }
private func fetchItems3(completion: @escaping (Error?) -> Void)) { ... }
答案 0 :(得分:0)
您可以保留一个额外的变量,以跟踪API调用何时完成。在完成块中,递增此变量。然后,当变量达到完成的API调用数量时,执行您的任务。
答案 1 :(得分:0)
我会使用DispatchGroup:
public void FetchItems(completion: @escaping (Error?) -> Void) {
let group = DispatchGroup()
group.enter()
fetchItems1() { error in
completion(error)
group.leave()
}
group.wait()
group.enter()
fetchItems2() { error in
completion(error)
group.leave()
}
// 3rd function call
}
在group.wait()
和group.enter()
调用次数相等之前,group.leave()
之后的代码才被调用。