需要帮助了解如何处理多级函数调用的完成处理程序

Need help understanding how to handle completion handlers with multi level function calls

我正在寻求一些处理我的代码的帮助。我正在使用 Alamofire 进行 GET 和 POST。因为它们是 运行 异步的,所以我需要使用完成处理程序,以便我可以将 JSON 数据保存到变量中并在以后使用它。

我的代码在下面,但我认为解释一下可能会使事情更清楚。 函数 x() 需要 JSON 数据并首先调用函数 y()。函数 y() 然后调用 getRequest 函数来实际执行 GET。我认为 getRequest 完成处理程序设置正确。它的设置使 y() 可以拥有自己的完成处理程序代码。我现在一直在研究如何将 JSON 数据输出到原始函数 x()。

我是否必须在函数 y() 中执行另一个 completion: @escaping (JSON?) -> Void)completion(response),然后在调用 y 的所有函数中添加完成代码,或者是否有一种方法可以导出 JSON 数据,以便我可以在函数 x() 中使用它?

func getRequest(url: String, params: [String:[String]] = ["":[""]], completion: @escaping (JSON?) -> Void) {

    let headers: HTTPHeaders = [ /* Header data goes here */ ]
    AF.request(url, method: .get, parameters: params, headers: headers).validate().responseJSON { (response) in
        // completion code goes here
        completion(response)
    }
    
}

func y() -> JSON {
    
    var jsonData = JSON(0)
    
    let url = "https://url.com/v1/"
    getRequest(url: url) { value in
        // Add completion code here too?
    }
    
    // Since get_request uses AF.request, the reply comes asynchronously and we don't return the actual data
    return jsonData

}

func x(token: String) -> JSON {
    
    let json = y()
    let jsonData = json["A"]

    // Rest of code goes here
}

一旦一个函数使用了异步函数,它也会变成异步的,因为它不能同步return数据,所以它也需要有自己的完成处理程序。

所以y应该定义成这样:

func y(completion: @escaping (JSON) -> Void) {
   // ...
   getRequest(url: url) { value in
      print(value) // or do something else with value
      completion(value) // return data via callback
   }
}

x 相同 - 它需要完成 return 数据或发出完成的信号:

func x(token: String, completion: @escaping () -> Void) {

   // ...
   y() { json in
      print(json)
      completion() // or return something via callback
   }
}