简体   繁体   中英

OperationQueue / DispatchGroup and recursion

I have a problem understanding how to use GCD when using asynchronous, recursive calls to the API.

Below is one of the three similar methods that contains the same logic, just for different data and API endpoint. If there is no next page request the method should finish and next method should start.

How would I make sure that fetchItems2 gets called after fetchItems1 finishes, and fetchItems3 after 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)) { ... }

You can keep an extra variable that keeps track of when the API calls are complete. In the completion block, increment this variable. Then, when the variable reaches the amount of API calls complete, perform your task.

I would use 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
 }

Code after group.wait() is not called until the number of group.enter() and group.leave() invocations is equal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM