简体   繁体   English

Async/await 相当于保存方法的完成块

[英]Async/await equivalent of saving a completion block of a method

I have a function in a NetworkManager class which loads an object Bar and returns it in a completion block.我在NetworkManager class 中有一个 function ,它加载一个 object Bar并将其返回到完成块中。 If my app is in the background, I save the completion block in a class FooManager like this:如果我的应用程序在后台,我将完成块保存在 class FooManager中,如下所示:

func getBar(
  withRequestId requestId: String,
  completion: (Bar) -> Void
) {
  let applicationState = UIApplication.shared.applicationState
  if applicationState == .background {
    let request = BarRequest(
      id: requestId,
      completion: completion
    )
    fooManager.request = request
    return
  }
  ...
}

Then, in FooManager when the applicationDidBecomeActive notification is received, I call the function again and pass in the completion handler, such that the original request can complete and return back to the caller:然后,在FooManager中,当收到applicationDidBecomeActive通知时,我再次调用 function 并传入完成处理程序,以便原始请求可以完成并返回给调用者:

func applicationDidBecomeActive() {
  guard let request else {
    return
  }
  network.getBar(
    withRequestId: request.id,
    completion: request.completion
  )
  self.request = nil
}

This works well.这很好用。 However, I'm now converting this function to async but I can't figure out how to do the equivalent of this without a completion block to save.但是,我现在正在将此 function 转换为异步,但我不知道如何在没有完成块保存的情况下执行此操作。

func getBar(withRequestId requestId: String,) async throws -> Config {
  let applicationState = UIApplication.shared.applicationState
  if applicationState == .background {
    let configRequest = ConfigRequest(
      id: requestId,
      completion: completion // Can't do this now
    )
    configManager.configRequest = configRequest
    return
  }
  ...
}

How can I do this, or something that's equivalent to this?我该怎么做,或者与此等效的事情?

I gather that getBar sometimes does nothing with the closure, but squirrels it away for future use, and sometimes presumably calls it.我收集到getBar有时对闭包没有任何作用,而是将其隐藏起来以备将来使用,有时可能会调用它。 If that is the case, that simply is not going to refactor nicely to an async function.如果是这样,那根本不会很好地重构为async function。

The contract with async functions is that they will always either return the value or throw (though, given that your closure did not have an error parameter to the closure, it seems that this should not be a function that throws ).async函数的约定是它们将始终返回值或抛出(尽管,鉴于您的闭包没有闭包的错误参数,看来这不应该是throws的 function )。 Besides, the code that runs after the async method is done is not passed as a parameter, but rather is back in the caller's “continuation”, that section of code after the await “suspension” point.此外,在async方法完成后运行的代码不会作为参数传递,而是返回到调用者的“延续”中,即await “暂停”点之后的那段代码。 You cannot save this continuation in a property, to call later.您不能将此延续保存在属性中,以便稍后调用。

So, if you really need this “save this block of code so I can call it later” pattern, you might want to just stay with the closure parameter.所以,如果你真的需要这种“保存这段代码以便我以后调用它”的模式,你可能只想保留闭包参数。 Just because you have a method that has a closure parameter does not mean that you have to make it async .仅仅因为您有一个具有闭包参数的方法并不意味着您必须使其成为async The point of async - await is to capture clear dependencies between asynchronous tasks, but if you need to save a block of code to call at some other point in time, a closure might be the best pattern. async - await的重点是捕获异步任务之间的明确依赖关系,但如果您需要保存一段代码以在其他时间点调用,那么闭包可能是最好的模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM