如何在RXSwfit中将CombineLatest用于两个公共主题

时间:2018-10-01 00:50:19

标签: ios swift rx-swift

我是RXSwift的新手,我尝试使用CombineLatest合并两个公共主题的最新结果

我试图做的事情

let sub1 = PublicSubject<Type1>()
let sub2 = PublicSubject<Type2>()

NetworkService1.fetch { sub1Value in 
   sub1.onNext(sub1Value)
}

NetworkService2.fetch { sub21Value in 
   sub2.onNext(sub2Value)
}

Observable.combineLatest(sub1.asObservable(), sub2.asObservable()) {
   val1, val2 in 
   // do something with val1 and val2
   // It seems it never hits this block
}

不确定我在做正确的事。

2 个答案:

答案 0 :(得分:0)

最好,如果您的NetworkService返回Observables。然后,您不必创建PublicSubjects,它会更漂亮。

我会这样:

let result1 = NetworkService1.shared.fetch()
let result2 = NetworkService2.shared.fetch()
Observable.combineLatest(result1, result2) { r1, r2 in
    // Do stuff with r1, r2 with are APIResult<[YourModel]> and return result
}.subscribe(onNext: { result in
    // You need to subscribe to run fetch methods
    // Do stuff with result of combine latest
}).disposed(by: disposeBag)

这是使用Alamofire并返回Observable的获取方法的示例:

func fetch() -> Observable<APIResult<[YourModel]>> {

    return Observable<APIResult<[YourModel]>>.create { (observer) -> Disposable in

        Alamofire.request(yourURLString,
                          method: .post,
                          parameters: nil,
                          headers: APIManager.headers())
            .responseJSON(completionHandler: { dataResponse in

                switch dataResponse.result {
                case .success(let value):

                    // parse value to someArray here
                    observer.onNext(APIResult.success(someArray))

                case .failure(_):
                    guard let code = dataResponse.response?.statusCode else {
                        observer.onNext(APIResult.failure(APIError.unknownError))
                        break
                    }
                    observer.onNext(APIResult.failure(APIError.networkError(code:code)))
                }

                observer.onCompleted()

            })

        return Disposables.create()
    }

}

APIResult也允许您传递错误:

enum APIResult<Value> {
    case success(Value)
    case failure(APIError)
}

答案 1 :(得分:0)

首先要进行几个观察:

  1. 没有PublicSubject,它是PublishSubject(可能只是一个错字;)

  2. 您无需调用asObservable()即可将PublishSubjects用作combineLatest

  3. 的参数
  4. 您必须订阅您的Observable(在这种情况下为Observable.combineLatest),否则将不会发生任何事情。

  5. 即使您正确订阅了Observable.combineLatest,也不会获得在订阅之前发出的值,因此必须在订阅之后触发这些获取调用。

因为一段代码值得一千个单词:

let disposeBag = DisposeBag()
let sub1 = PublishSubject<String>()
let sub2 = PublishSubject<String>()

Observable.combineLatest(sub1, sub2) {
  val1, val2 in
  // do something with val1 and val2
  // IT SHOULD WORK NOW
}.subscribe().disposed(by: disposeBag)

NetworkService1.fetch { sub1Value in 
  sub1.onNext(sub1Value)
}

NetworkService2.fetch { sub2Value in 
  sub2.onNext(sub2Value)
}