【问题标题】:Async function not handled by completion handler完成处理程序未处理异步函数
【发布时间】:2019-01-13 00:45:49
【问题描述】:

我正在使用谷歌地图距离矩阵 api 并使用完成处理程序来传递我的异步函数调用,如下所示:

func configureRoute(origin:String,destination:String, completionHandler: @escaping (_ duration:Int) -> ()){
    let jsonURL = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=place_id:\(origin)&destinations=place_id:\(destination)&key=MYAPI"
    guard let url = URL(string: jsonURL ) else {return}
    print(jsonURL)

    URLSession.shared.dataTask(with: url) { (data, response, err) in
        guard let data = data else {return}
        do {
            let route = try JSONDecoder().decode(Welcome.self, from: data)
            // print(self.durations)
            completionHandler(route.rows[0].elements[0].duration.value)
        }
        catch let jsonErr {
        }
        let dataAsString = String(data: data, encoding: .utf8)
    }.resume()
}

然后我尝试像这样使用该结果,但是我的输出结果仍然是空白的,并且我无法使用我收到的任何呼叫。我对强制处理程序不太擅长,所以如果有人可以让我知道我做错了什么?

func majorConfigure() {
    permutations(placeID.count, &placeID, origin: startPlaceID, destination: endPlaceID)
    for eachArray in finalRoutes {
        for i in 0..<(eachArray.count-1) {
            configureRoute(origin: eachArray[i], destination: eachArray[i+1]){
                duration in
                self.durations.append(duration)
            }
        }
        groupedDurations.append(durations)
        durations.removeAll()
    }
    print(groupedDurations)
}

使用 Dispatch 组后,这是我更新的代码:

 func majorConfigure(){
    permutations(placeID.count, &placeID, origin: startPlaceID, destination: endPlaceID)
    let dispatchGroup = DispatchGroup()
    for eachArray in finalRoutes{
        for i in 0..<(eachArray.count-1){
            dispatchGroup.enter()
            configureRoute(origin: eachArray[i], destination: eachArray[i+1]){
                duration in
                self.durations.append(duration)
                print(self.groupedDurations)
                dispatchGroup.leave()
            }
        }
        dispatchGroup.notify(queue: .main){
            self.groupedDurations.append(self.durations)
            self.durations.removeAll()
        }
    }

 }

我打印 groupedDurations 的结果是:

[]
[]
[]
[]
[]
[]

【问题讨论】:

  • 你试过浏览器中的网址吗?你有任何回应吗?
  • 是的,有回应。

标签: ios asynchronous swift4 google-distancematrix-api


【解决方案1】:

试一试:

    func majorConfigure() {
permutations(placeID.count, &placeID, origin: startPlaceID, destination: endPlaceID)
for eachArray in finalRoutes {
    for i in 0..<(eachArray.count-1) {
        configureRoute(origin: eachArray[i], destination: eachArray[i+1]){
            duration in
            self.durations.append(duration)
               if i == eachArray.count - 1{
                groupedDurations.append(durations)
               }
            if i == eachArray.count - 1 && eachArray == finalRoutes.last! {
                 print(groupedDurations)
                 durations.removeAll()
              } 
        }
    }


}

}

编辑答案

您可以通过这种方式实现:

var indexFinalRoutes = 0 
var indexEachArray = 0

func loopFinalRoutes(){
    self.indexEachArray = 0
    let eachArray = finalRoutes[indexFinalRoutes]
    loopEachArray(eachArray: eachArray) { (success) in
        self.indexFinalRoutes = self.indexFinalRoutes + 1
        if self.indexFinalRoutes < self.finalRoutes.count - 1{
            self.loopFinalRoutes()
        }else{
            self.indexFinalRoutes = 0
            print(self.groupedDurations)
        }
    }
}

func loopEachArray(eachArray : [String] ,
                   completion: @escaping (_ success:Bool) -> Void){

    if indexEachArray + 1 < eachArray.count - 1 {
        configureRoute(origin: eachArray[indexEachArray], destination: eachArray[indexEachArray+1]){
            duration in
            self.durations.append(duration)
            self.indexEachArray = self.indexEachArray + 1
            let nextEachArray = self.finalRoutes[self.indexFinalRoutes]
            self.loopEachArray(eachArray: nextEachArray, completion: completion)
        }
    }else{
        groupedDurations.append(durations)
        durations.removeAll()
        completion(true)
    }

}

从您的 majorConfigure 函数调用 loopFinalRoutes 函数,您将获得输出。

【讨论】:

  • 我应该将它与完成处理程序一起使用,还是不使用?
  • 这个函数正在使用完成处理程序,检查它是否正在打印 groupDurations
  • 发生了一些奇怪的事情。我在语句上放了一个断点,它没有被调用,也没有打印任何东西,所以我猜这个语句没有被调用。
  • 我得到一个输出,但是当我输入 4 个目的地时,输出只是一个包含一个数组的字典,包含 2 个元素,而输出应该是一个字典,包含 2 个数组,每个数组包含 3 个元素。我应该在循环内还是在 majorConfigure 本身中调用 loopFinalRoutes?
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多