【发布时间】:2015-11-20 08:44:31
【问题描述】:
假设有两个对 API 的异步请求需要按顺序执行。 第一个请求的结果是字典,第二个请求使用它来获取最终字典。 Interstellar (https://github.com/JensRavens/Interstellar) 允许以一种按顺序依次执行异步请求的方式链接异步请求: 例如:
typealias JSONDictionary = [String: AnyObject]
func create(parameters: JSONDictionary, completion: Result<JSONDictionary> -> Void) {
Request.POST("objects", parameters: parameters, completion: completion)
}
func verify(parameters: JSONDictionary, completion: Result<JSONDictionary> -> Void) {
guard let id = parameters["id"] as? String else {
let error = NSError(domain: "", code: 401, userInfo: nil)
completion(.Error(error))
return
}
Request.POST(String(format: "objects/%@/verify", id), parameters: nil, completion: completion)
}
“create”需要先执行,结果字典将用于执行“verify”: 这很好用:
address.flatMap(Address.create).flatMap(Address.verify)
.next { dictionary in
expectation.fulfill()
}
.error { error in
print("There was a an error: \(message)")
}
address.update(self.parameters)
下面的代码(来自星际幻灯片):
infix operator >>> { associativity left precedence 160 }
func >>> <A, B> (left: Signal<A>, right: A->Result<B>) -> Signal<B> {
return left.flatMap(right)
}
func >>> <A, B> (left: Signal<A>, right: (A, (Result<B> -> Void)) -> Void) -> Signal<B> {
return left.flatMap(right)
}
func >>> <A, B> (left: Signal<A>, right: A -> B) -> Signal<B> {
return left.flatMap(right)
}
可以使用:
address >>> Address.create >>> Address.verify
这更清楚。但是,如果验证被定义为(接受 id 而不是字典):
func verify2(id: String, completion: Result<[String: String]> -> Void) { ... }
为了链接它,我定义了另一个函数:
static func idValue(dictionary: JSONDictionary, completion: Result<String> -> Void) { ... )
这基本上是从字典中解压缩 id 键的值(将字典转换为字符串),而不是我可以使用的:
address >>> Address.create >>> Address.idValue >>> Address.verify2
这是 FRP 的常见做法吗?我可以避开中间的那一步吗?
【问题讨论】: