我正在尝试实现嵌套的Alamofire请求:-第一个请求调用代码-第二个请求使用第一个请求中获得的代码调用结果
此外,我猜想DispatchQueue对象有问题,我当时在考虑对第二个请求使用DispatchQueue.main.async,但是这里不接受。
在下面的行中,第二个请求返回的结果为零,因为它没有包含在第一个请求中找到的代码。
func fetch(jan: String) {
AF.request("https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?appid=\(appId)&jan=\(jan)&hits=50").responseDecodable(of: Welcome.self , queue: DispatchQueue.main) { response in
let boncode1 = String("\(response.value?.resultSet.the0.result.the0?.code)")
print(boncode1)
AF.request("https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemLookup?appid=\(self.appId)&itemcode=\(boncode1)").responseDecodable(of: troisViewController.Welcome.self , queue: DispatchQueue.main) { response in
print("\(response.value?.resultSet.the0.result.the0?.name ?? "is nil" )")
}
}
}
我希望有人已经处理过类似的问题,
提前谢谢您
Alamofire不提供自己的异步原语。相反,您可以将Alamofire的请求与现有的原语组合在一起,也可以提供自己的原语。这里最简单的解决方案是嵌套调用:
AF.request(...).responseDecodable(of: ...) { outer in
// Handle outer response.
AF.request(...).responseDecodable(of: ...) { inner in
// Handle inner response.
}
}
此外,不需要将DispatchQueue.main
传递给Alamofire,因为这是您始终要调用响应处理程序的默认队列。
只要您需要两次服务调用,嵌套函数就可以满足您的需求。但是,假设您需要处理5个甚至更多服务呼叫的结果,那肯定是Pyramid of Doom噩梦。
为了避免它,我建议您看一下DispatchGroup API并学习如何使用它。
组允许您聚合一组任务并同步组上的行为。您将多个工作项附加到一个组,并安排它们在同一队列或不同队列上异步执行。当所有工作项完成执行时,组将执行其完成处理程序。您也可以同步等待组中的所有任务完成执行。
因此您可以像这样实现您的功能:
func fetch(jan: String) {
// Local variable
var boncode1: String = ""
// Create group
let dispatchGroup = DispatchGroup()
// Fetch data from the first service
let url_1 = "https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?appid=\(appId)&jan=\(jan)&hits=50"
// Indicate that the first block of work (first service call) has entered the group.
dispatchGroup.enter()
AF.request(url_1).responseDecodable(of: Welcome.self) { response in
// Store data in local variable
boncode1 = String("\(response.value?.resultSet.the0.result.the0?.code)")
// Indicate that the first block in the group finished executing.
dispatchGroup.leave()
}
// Fetch data from the second service
let url_2 = "https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemLookup?appid=\(self.appId)&itemcode=\(boncode1)"
//Indicate that the second block of work (second service call) has entered the group.
dispatchGroup.enter()
AF.request(url_2).responseDecodable(of: troisViewController.Welcome.self) { response in
// handle response from the second service if you need it
// Indicate that the second block in the group finished executing.
dispatchGroup.leave()
}
// This function schedules a notification block to be submitted to the specified queue
// when all blocks associated with the dispatch group have completed.
dispatchGroup.notify(queue: .main) {
// process results of 2 service calls
}
}