如何在Swift中处理异步请求? [英] How do I handle async requests in Swift?
问题描述
我在其中一项功能中进行了Web服务调用。我在构造它时遇到了麻烦,因此逻辑是干净的并且不是多余的。这是我的财产:
I make a web service call in one of my functions. I'm having trouble how to structure it so the logic is clean and not redundant. Here's what I have:
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()
来称呼它。某件事感觉不对..设置 deferredTask
变量是避免冗余代码的好方法吗?
Then I call this using MyInstance.getTimes()
. Something doesn't feel right though.. is setting up a deferredTask
variable a good way to avoid redundant code?
此外,当我从另一个函数调用此函数时,将使用 var test = MyInstance.getTimes()
。但这意味着 test
处于异步状态,在Web服务在 getTimes $中完成之前,我无法在其他功能中使用它。 c $ c>。
Also, when I call this from another function, I would use var test = MyInstance.getTimes()
. But this means test
is in an async state and I can't use it in my other function until the web service is finished in getTimes
.
在Swift中处理此问题的好方法是什么?
What's a good way to handle this in Swift?
推荐答案
正如您正确地说的那样,您不能这样做:
As you rightly say, you cannot do this:
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 deferredTask()
从周围的闭包中返回-而不是从 getTimes
中返回。您不能从函数调用中异步返回值!这就是异步的本质。
The problem, as I think you are correctly trying to say, is that return deferredTask()
is returned from the surrounding closure - not from getTimes
. You cannot asynchronously return a value from a function call! That is the nature of asynchrony.
典型的标准解决方案是编写 getTimes
本身以接受回调函数,例如它的参数。它本身不返回任何内容。异步方法完成后,它将调用回调,从而在将来的某个时间将信息返回给原始调用者。
A typical standard solution is to write getTimes
itself to accept a callback function as its parameter. It itself returns nothing. When the asynchronous method is finished, it calls the callback, thus getting the info back, at some future time, to the original caller.
为了向您展示我的意思,我将完全从故事中删除您的 deferredTask
,而只专注于异步任务和回调。因此,我们将得到:
To show you what I mean, I'm going to remove your deferredTask
entirely from the story and just concentrate on the asynchronous task and the callback. So we would have this:
public func getTimes(f:(Any) -> Void) -> () {
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) {
(data, response, error) in
// ...
f(whatever)
}.resume()
}
此体系结构的要点是对 f(whatever)
的呼叫实际上可以追溯到谁首先将我们交给 f
的人-特别是如果该实体将自己
放在某个地方。
The point of this architecture is that the call to f(whatever)
effectively goes back to whoever handed us f
in the first place - especially if that entity put self
into it somewhere.
这篇关于如何在Swift中处理异步请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!