ios - 如何映射 RxSwift Observable 和 Result

标签 ios swift rx-swift reactivex

我有一个简短的问题:

  • 我有一个返回 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/

相关文章:

rx-swift - 将 PublishRelay 转换为可选元素的BehaviorRelay

ios - 如何在 RxSwift 中将 UISwitch 绑定(bind)到 UIButton 启用?

javascript - PhoneGap 应用程序无法与 Google Analytics 一起使用

iphone - 是否可以获取从 iTunes 添加的视频的路径?

swift - swift 中的 UnsafeMutablePointer 替代 Obj-C 中大小合适的 C 数组

ios - 带有白色边框的 alertController

ios - RXSwift,一个作为变量的结构

android - 在已编译的应用程序中运行Flutter BuilderRunner

ios - 获取 UITableViewCell 索引以响应位于 TableView 内 TableView 中的按钮单击的正确方法?

ios - Swift tableview在删除单元格过程indexPath.row问题