我有一个简短的问题:
- 我有一个返回
Observable<Result<String, RequestError>>
的网络请求,我们称它为requestToken
- 如果此请求成功,我想使用
String
( token )执行另一个返回Observable<Result<NSDictionary, RequestError>>
的请求,我们称它为requestData
- 当第二个请求返回时,我想将 token 合并到它的字典中
- 最后我想从
Observable<Result<String, RequestError>>
映射至Observable<Result<NSDictionary, RequestError>>
如果我的代码中没有多个嵌套级别,我如何才能实现这一点?
这就是我今天拥有的:
requestToken()
.flatMap({ result -> Observable<Result<NSDictionary, RequestError>> in
switch result {
case .success(let token):
return requestData(token: token).map({ $0.map({ $0 + ["token": token] }) })
case .failure(let error):
return Observable.of(.failure(error))
}
})
最佳答案
更新:
这是一个详细的示例,希望对您有所帮助:
enum RequestError: Error {
case unknown
}
func requestToken() -> Observable<String> {
return Observable.create { observer in
let success = true
if success {
observer.onNext("MyTokenValue")
observer.onCompleted()
} else {
observer.onError(RequestError.unknown)
}
return Disposables.create()
}
}
func requestData(token: String) -> Observable<[String: Any]> {
return Observable<[String: Any]>.create { observer in
let success = false
if success {
observer.onNext(["uid": 007])
observer.onCompleted()
} else {
observer.onError(RequestError.unknown)
}
return Disposables.create()
}
.map { (data: [String: Any]) in
var newData = data
newData["token"] = token
return newData
}
}
requestToken() // () -> Observable<String>
.flatMapLatest(requestData) // Observable<String> -> Observable<[String: Any]>
.materialize() // Observable<[String: Any]> -> Observable<Event<[String: Any]>>
.subscribe(onNext: { event in
switch event {
case .next(let dictionary):
print("onNext:", dictionary)
case .error(let error as RequestError):
print("onRequestError:", error)
case .error(let error):
print("onOtherError:", error)
case .completed:
print("onCompleted")
}
})
.disposed(by: disposeBag)
原文:
我认为使用 materialize()
实现它要容易得多,而且额外的工作更少:
func requestToken() -> Observable<String> { return .empty() }
func requestData(token: String) -> Observable<NSDictionary> { return .empty() }
enum RequestError: Error {}
requestToken()
.flatMapLatest(requestData)
.materialize()
.subscribe(onNext: { event in
switch event {
case .next(let dictionary):
print("onNext:", dictionary)
case .error(let error as RequestError):
print("onRequestError:", error)
case .error(let error):
print("onOtherError:", error)
case .completed:
print("onCompleted")
}
})
.disposed(by: disposeBag)
希望这可能有所帮助。
关于ios - 如何映射 RxSwift Observable 和 Result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42426869/