RxSwift合并了不同类型的Observable

时间:2016-08-20 03:04:49

标签: swift frp rx-swift

如何在RxSwift中合并两种不同类型的Observable

例如:

var a: Observable<Int>
var b: Observable<Void>
由于类型参数不同,

Observable.of(a,b).merge()是不可能的。

2 个答案:

答案 0 :(得分:23)

merge他们,他们需要为Element设置相同的类型。

因此,一种选择是丢弃他们的类型信息并转换为AnyObject。现在他们可以合并:

let stringSubject = PublishSubject<String>()
let stringObservable = stringSubject.asObservable().map { $0 as AnyObject }

let intSubject = PublishSubject<Int>()
let intObservable = intSubject.asObservable().map { $0 as AnyObject }

Observable.of(stringObservable, intObservable).merge()
    .subscribeNext { print($0) }
    .addDisposableTo(disposeBag)

stringSubject.onNext("a")
stringSubject.onNext("b")
intSubject.onNext(1)
intSubject.onNext(2)
stringSubject.onNext("c")

输出:

  

一个
  b
  1
  2
  ç

另一个选择是在枚举中包装:

enum Container {
    case S(String)
    case I(Int)
}

let stringSubject = PublishSubject<String>()
let stringObservable = stringSubject.asObservable().map { Container.S($0) }

let intSubject = PublishSubject<Int>()
let intObservable = intSubject.asObservable().map { Container.I($0) }

Observable.of(stringObservable, intObservable).merge()
    .subscribeNext { e in
        switch e {
        case .S(let str):
            print("next element is a STRING: \(str)")
        case .I(let int):
            print("next element is an INT: \(int)")
        }
    }
    .addDisposableTo(disposeBag)

stringSubject.onNext("a")
stringSubject.onNext("b")
intSubject.onNext(1)
intSubject.onNext(2)
stringSubject.onNext("c")

输出:

  

下一个元素是STRING:a   下一个元素是STRING:b
  下一个元素是INT:1
  下一个元素是INT:2
  下一个元素是STRING:c

对于可以组合不同类型Observable的其他运算符(例如zipcombineLatest),没有一个与merge完全相同。但是,检查一下。它们可能更适合您的要求。

答案 1 :(得分:1)

如果要合并两个可观察对象,但不需要Element的值,并且想要一种使用Expression of type 'AnyObject' is unused选项时摆脱.map { $0 as AnyObject }的方法:< / p>

var a = PublishSubject<Int>()
var b = PublishSubject<Void>()

let observable = Observable.merge(a.map { _ in return Void() }, b)