OperationQueue / DispatchGroup和递归

时间:2019-07-10 19:57:25

标签: ios swift

在对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)) { ... }

2 个答案:

答案 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()之后的代码才被调用。