Swift 嵌套Alamofire请求和异步调度队列

Swift 嵌套Alamofire请求和异步调度队列,swift,api,alamofire,grand-central-dispatch,dispatch-async,Swift,Api,Alamofire,Grand Central Dispatch,Dispatch Async,我正在尝试实现嵌套的Alamofire请求: -第一个请求调用一个代码 -第二个请求使用在第一个请求中获得的代码调用结果 此外,我想DispatchQueue对象可能有问题,我想对第二个请求使用DispatchQueue.main.async,但这里不接受 在下面的几行中,第二个请求返回一个nil结果,因为它没有包含在第一个请求中找到的代码 func fetch(jan: String) { AF.request("https://shopping.yahooapis.jp/Shop

我正在尝试实现嵌套的Alamofire请求: -第一个请求调用一个代码 -第二个请求使用在第一个请求中获得的代码调用结果

此外,我想DispatchQueue对象可能有问题,我想对第二个请求使用DispatchQueue.main.async,但这里不接受

在下面的几行中,第二个请求返回一个nil结果,因为它没有包含在第一个请求中找到的代码

    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
//处理外部响应。
AF.request(…).responseDecodable(of:…){inner in
//处理内心的反应。
}
}

此外,无需将
DispatchQueue.main
传递给Alamofire,因为这是响应处理程序被调用的默认队列。

只要您需要两个服务调用,那么嵌套函数可能适合您的需要。 但是,假设您需要处理5次甚至更多服务调用的结果,这肯定是一场噩梦

为了避免这种情况,我建议您看看API并学习如何利用它

组允许您聚合一组任务并同步组上的行为。您可以将多个工作项附加到一个组,并将它们安排在同一队列或不同队列上异步执行。当所有工作项完成执行时,组将执行其完成处理程序。您还可以同步等待组中的所有任务完成执行

因此,您可以像这样实现您的功能:

func fetch(jan:String){
//局部变量
var boncode1:String=“”
//创建组
让dispatchGroup=dispatchGroup()
//从第一个服务获取数据
让url_1=”https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?appid=\(appId)&jan=\(jan)&hits=50“
//指示第一个工作块(第一次服务呼叫)已进入组。
dispatchGroup.enter()
AF.request(url_1).responseDecodable(of:Welcome.self){response in
//将数据存储在局部变量中
boncode1=String(\(response.value?.resultSet.the0.result.the0?.code))
//指示组中的第一个块已完成执行。
dispatchGroup.leave()
}
//从第二个服务获取数据
让url_2=”https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemLookup?appid=\(self.appId)&itemcode=\(boncode1)
//指示第二个工作块(第二次服务呼叫)已进入组。
dispatchGroup.enter()
AF.request(url_2).responseDecodable(of:troisViewController.Welcome.self){response in
//如果需要,处理来自第二个服务的响应
//指示组中的第二个块已完成执行。
dispatchGroup.leave()
}
//此函数用于调度要提交到指定队列的通知块
//与调度组关联的所有块完成时。
dispatchGroup.notify(队列:.main){
//处理2个服务调用的结果
}
}

queue:参数接收DispatchQueue对象,而
DispatchQueue.main.async
是一个不返回任何内容的方法。完成处理程序总是异步返回,因此我认为您不必担心这一点。您可以做的是创建一个自定义DispatchQueue并传递它,而不是DispatchQueue.main。ie:
DispatchQueue(标签:“com.your domain.request thread”,qos:.utility)
关于返回nil的第二个请求,如果不运行代码,很难判断这是对API的调用问题,还是Swift方面的问题。例如,
boncode1
是否分配给您期望的值?在第二个请求中,它似乎被正确地插入了。非常感谢您的回答,我选择了第一个选项,它似乎表现得很好,只需一个简单的“if-else”。不幸的是,调度组方法没有成功。由于这是两个不同的API调用,我希望“if else”方法不会降低数据提取的速度性能。好吧,如果我们有两个或更多异步调用,我们不需要每次离开调度组时都有“dispatchGroup.notify(queue:.main)”块?