有没有办法从惰性或计算属性调用异步函数?
struct Item {
lazy var name: String = {
API.requestThing({ (string: String) in // Xcode didn't like this
return string // this would not work here
})
}()
}
class API {
class func requestThing(completion: String -> Void) {
completion("string")
}
}
答案 0 :(得分:1)
API.requestThing中的完成处理程序返回一个String,但它应该没有返回值:
(completion: String -> Void)
我让这个工作:
struct Item {
lazy var name: String = {
API.requestThing({ (string: String) in
return string
})
}()
}
class API {
class func requestThing(completion: String -> String) -> String {
return completion("string")
}
}
答案 1 :(得分:0)
首先,requestThing
返回()
(即无效),而不是String
。因此,以下表达式的类型也是()
而不是String
:
API.requestThing { string in
return string
}
其次,对requestThing
的调用是异步的,所以即使你将name
定义为一个惰性var,对var body函数的调用仍然是synchronous
并将立即返回。
因此,如果您可以将name
转换为如下函数:
func name(completion: String -> ()) {
API.requestThing { string in
completion(string)
}
}
// Later you call it in this way
myItem.name { name in
// use the value of name
}
如果您想要缓存检索到的值,可以将Item
修改为class
并使用以下代码
class Item {
private var nameValue: String?
func name(completion: String -> ()) {
if let value = nameValue {
// return cached value
return completion(value)
} else {
// request value
API.requestThing { string in
// cache retrieved value
self.nameValue = string
// return retrieved value
completion(string)
}
}
}
}
答案 2 :(得分:0)
没有充分的理由使用" lazy"在这种情况下。懒惰是用于初始化。只需创建一个普通的func并传递一个完成处理程序。
答案 3 :(得分:0)
可能没有令人信服的理由这样做,但以下方法似乎是合理的:
而是拥有String
类型的变量 - 我们有时需要一个&#34; Future&#34;那个东西,例如Future<String>
。未来代表异步操作的最终结果 - 这正是您问题中给出的内容。
未来本身就是一个正常的&#34;变量也可以延迟评估。它还没有最终的价值。这意味着,只有在明确请求时才会启动基础任务(例如 lazily )。从设计或架构的角度来看,这可能是有道理的。
func fetchString() -> Future<String> { ... }
lazy var name: Future<String> = fetchString()
稍后在您的代码中,您将获得如下变量:
item.name.map { string in
print(string)
}
如果这是第一次访问惰性属性,它将启动计算字符串的底层异步操作。然后,当变量可用时,map
函数中提供的映射函数将以变量作为参数调用 - 可能也会在一段时间之后调用。
否则(如果这不是第一次访问),它只会在参数可用时提供参数中的字符串。
由于操作可能会失败,因此未来&#34;还提供了处理此问题的方法:
item.name.map { string in
print(string)
}.onFailure { error in
print("Error: \(error)")
}
另请参阅:https://en.wikipedia.org/wiki/Futures_and_promises
在Swift和Objective-C中有Futures的实现,通常也被称为&#34; Promise&#34;。