Swift 如何使异步运行的地理编码函数在后续代码之前完成?

Swift 如何使异步运行的地理编码函数在后续代码之前完成?,swift,asynchronous,async-await,swiftui,Swift,Asynchronous,Async Await,Swiftui,我有一个在函数内部调用的前向地理编码函数: class AnnotationsVM: ObservableObject { @ObservedObject var VModel: ViewModel func addNextAnnotation(address: String) { self.VModel.fetchCoords(address: address) DispatchQueue.main.asyncAfter(deadline:

我有一个在函数内部调用的前向地理编码函数:

class AnnotationsVM: ObservableObject {

    @ObservedObject var VModel: ViewModel

    func addNextAnnotation(address: String) {
        self.VModel.fetchCoords(address: address)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            //Without the asyncAfter, this code runs before the fetchCoords() function is run.
        }
    }
}
fetchCoords函数的定义如下:

class ViewModel: ObservableObject {

    @Published lat: Double?
    @Published lon: Double?

    func fetchCoords(address: String){
        var latitude: Double? = 0.0
        var longitude: Double? = 0.0
        self.getLocation(from: address) { coordinates in
            self.location = coordinates // Assign to a local variable for further processing
            self.lon = coordinates?.longitude
            self.lat = coordinates?.latitude
        }
    }
}

我的问题是,有没有一种更有效的方法来执行DispatchQueue,而不仅仅是固定在任意时间(我使用了0.1秒,但更希望代码在fetchCoords运行后立即运行).

你是正确的,你只是等待一些任意的时间来希望数据可用,这是一种非常粗糙和脆弱的方法

有许多模式可以处理异步行为,但这里可以做的一件事是传递一个完成处理程序,该处理程序将在
fetchCoords
完成时调用

因此,假设这个完成处理程序接受坐标(为简单起见,我将使用2个double):


当然,这只是一种概念性的方法(例如,它不处理错误),但它应该让您走上正确的轨道。

您是正确的,您只是等待一些任意的时间来希望数据可用是一种非常粗糙和脆弱的方法

有许多模式可以处理异步行为,但这里可以做的一件事是传递一个完成处理程序,该处理程序将在
fetchCoords
完成时调用

因此,假设这个完成处理程序接受坐标(为简单起见,我将使用2个double):


当然,这只是一种概念性的方法(例如,它不处理错误),但它应该让您走上正确的道路。

是不是
getLocation
一个异步函数?是的,我非常确定……如果我在完成处理程序中添加print语句,并在addnextanotation函数中调用函数后添加print语句,它在fetchCoords调用之后打印行,然后再打印另一行。所以,这绝对不是这样做的。它不仅效率不高,而且非常粗糙和脆弱,因为您无法保证异步请求坐标需要多长时间。这里有多种模式可供使用,例如与您自己的完成处理程序一起使用(即,
fetchCoords
可以获取一个完成处理程序参数,您可以从
getLocation
的完成处理程序中调用该参数,该完成处理程序是什么样子的?
getLocation
是一个异步函数吗?是的,我非常确定……如果我在完成处理程序中添加print语句和print语句在AddNextAnotation函数中调用该函数后,它会在fetchCoords调用后打印行,然后再打印另一行。因此,这绝对不是执行此操作的方法。它不仅效率低下,而且非常粗糙和脆弱,因为您无法保证异步请求坐标所需的时间。有多种方法这里要使用的ple模式,例如与您自己的完成处理程序一起使用(即,
fetchCoords
可以获取一个完成处理程序参数,您可以从
getLocation
的完成处理程序中调用该参数,该完成处理程序看起来会是什么样子?哇,完成处理程序似乎在很多情况下都会非常有用……谢谢,伙计,完成处理程序看起来很有用在很多情况下都会非常有帮助…谢谢你
func fetchCoords(address: String, completion: @escaping (Double, Double) -> Void){
   self.getLocation(from: address) { coordinates in

      self.location = coordinates

      if let lat = coordinates?latitude, let lon = coordinates?longitude {
          completion(lat, lon)
      }
}
func addNextAnnotation(address: String) {
   self.VModel.fetchCoords(address: address) { lat, lon in
      // do something with lat and long
   }
}