如何在Swift中处理异步请求?
我在我的一个函数中进行web服务调用。我有麻烦如何构造它,使逻辑是干净的,而不是多余的。以下是我所拥有的:如何在Swift中处理异步请求?,swift,closures,Swift,Closures,我在我的一个函数中进行web服务调用。我有麻烦如何构造它,使逻辑是干净的,而不是多余的。以下是我所拥有的: public func getTimes() -> [TimeName: MyResult] { let deferredTask: () -> [TimeName: MyResult] = { var computed = self.computeTimes() // Do something return comput
public func getTimes() -> [TimeName: MyResult] {
let deferredTask: () -> [TimeName: MyResult] = {
var computed = self.computeTimes()
// Do something
return computed
}
// Calculate timezone
if let tz = timezone {
timeZone = tz
return deferredTask()
} else {
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) {
(data, response, error) in
// Do something with data
return deferredTask() // Getting a compiler error here btw: is not convertible to 'Void'
}.resume()
}
}
然后我使用MyInstance.getTimes()
调用它。但有些事情感觉不对劲。。设置delferredtask
变量是否是避免冗余代码的好方法
另外,当我从另一个函数调用它时,我会使用var test=MyInstance.getTimes()
。但这意味着test
处于异步状态,在getTimes
中完成web服务之前,我无法在其他函数中使用它
用Swift处理这个问题的好方法是什么?正如你正确地说的,你不能这样做:
public func getTimes() -> [TimeName: MyResult] {
let deferredTask: () -> [TimeName: MyResult] = {
var computed = self.computeTimes()
// Do something
return computed
}
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) {
(data, response, error) in
// Do something with data
return deferredTask()
}.resume()
}
正如我认为您所说的,问题在于return delferredtask()
是从周围的闭包返回的,而不是从getTimes
返回的。不能从函数调用异步返回值!这就是异步的本质
典型的标准解决方案是编写getTimes
本身,以接受回调函数作为其参数。它本身什么也不返回。异步方法完成后,将调用回调函数,从而在将来某个时间将信息返回给原始调用方
为了向您展示我的意思,我将从故事中完全删除您的deferredTask
,只关注异步任务和回调。所以我们会有这个:
public func getTimes(f:(Any) -> Void) -> () {
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) {
(data, response, error) in
// ...
f(whatever)
}.resume()
}
这种架构的要点是,对f(whatever)
的调用实际上可以追溯到最初交给我们f
的人——特别是如果该实体将self
放在某个地方