【问题标题】:RxSwift merge different kind of ObservablesRxSwift 合并不同类型的 Observables
【发布时间】:2016-12-27 06:21:49
【问题描述】:

我应该如何在 RxSwift 中合并 2 种不同类型的 Observables?

例如:

var a: Observable<Int>
var b: Observable<Void>

Observable.of(a,b).merge() 是不可能的,因为类型参数不同。

【问题讨论】:

    标签: swift frp rx-swift


    【解决方案1】:

    对于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
    c

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

    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")
    

    输出:

    下一个元素是一个字符串:a
    下一个元素是一个字符串:b
    下一个元素是一个 INT:1
    下一个元素是一个 INT:2
    下一个元素是一个字符串:c

    至于可以组合不同类型的Observables 的其他运算符(如zipcombineLatest),没有一个像merge 那样工作。但是,请检查这些。它们可能更适合您的要求。

    【讨论】:

      【解决方案2】:

      如果您想合并两个 observable,但不需要 Element 的值,并且想要在使用 .map { $0 as AnyObject } 选项时摆脱 Expression of type 'AnyObject' is unused

      var a = PublishSubject<Int>()
      var b = PublishSubject<Void>()
      
      let observable = Observable.merge(a.map { _ in return Void() }, b)
      

      【讨论】:

        猜你喜欢
        • 2016-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多