首页 > 解决方案 > 关于 `withLatestFrom` 的使用问题

问题描述

我是 RxSwift 的新手。我遇到了问题

要求是这样的,

  1. 如果有从流 A、B 和 C 返回的值,那么我会在流 X 上发出一个事件(布尔值)
  2. 每当streamX返回真实值时,我想对流A、B和C进行快照并做一些事情
  3. 由于类设计的原因,我们需要将动作 1 和 2 分成两个 Rx 块

下面是我的代码的简化版本

class parent {
    let streamA: BehaviorRelay<String?> = BehaviorRelay(value: nil)
    let streamB: BehaviorRelay<String?> = BehaviorRelay(value: nil)
    let streamC: BehaviorRelay<String?> = BehaviorRelay(value: nil)
    let moduleVisibility: BehaviorRelay<Bool?> = BehaviorRelay(value: nil)

    BehaviorRelay.combineLatest(streamA.filterNil(), streamB.filterNil(), streamB.filterNil()).subscribe { [weak self ] _, _, _ in
            guard let self = self else { return }
            self.moduleVisibility.accept(true)
        }.disposed(by: bag)
}

class childClass {
   moduleVisibility.filterNil().filter({ $0 == true}).withLatestFrom(Observable.combineLatest(streamA.filterNil(), streamB.filterNil(), streamC.filterNil())).observeOn(MainScheduler.instance).subscribe(onNext: { valueA, valueB, valueC in
            // This line does not get called
            print("\(valueA) \(valueB) \(valueC)")
        }).disposed(by: bag)
}

// then I called
streamA.accept("A")
streamB.accept("B")
streamC.accept("C")
// but the block @ childClass does not get fired

我检查流中有事件moduleVisibility。但它说块没有价值withLatestFrom

想知道我的块设置是否不正确。因为我认为A B C正在导致事件,X 虽然有来自的事件X,但必须有来自的值A B C

或者我需要在 main.thread 上观察?任何帮助将不胜感激:祈祷

标签: rx-swift

解决方案


格式化代码

import RxSwift
import RxCocoa

func ignoreNil<A>(x: A?) -> Observable<A> {
    return x.map { Observable.just($0) } ?? Observable.empty()
}

class Parent {
    let bag = DisposeBag()
    let streamA: BehaviorRelay<String?> = BehaviorRelay(value: nil)
    let streamB: BehaviorRelay<String?> = BehaviorRelay(value: nil)
    let streamC: BehaviorRelay<String?> = BehaviorRelay(value: nil)
    let moduleVisibility: BehaviorRelay<Bool?> = BehaviorRelay(value: nil)
    
    init() {
        BehaviorRelay
            .combineLatest(
                streamA.flatMap(ignoreNil),
                streamB.flatMap(ignoreNil),
                streamC.flatMap(ignoreNil)
            ).subscribe { [weak self ] _, _, _ in
                guard let self = self else { return }
                
                print("moduleVisibility ")
                self.moduleVisibility.accept(true)
            }.disposed(by: bag)
    }
}

class Child: Parent {
    override init() {
        super.init()
        moduleVisibility
            .flatMap(ignoreNil)
            .filter({ $0 == true})
            .withLatestFrom(
                Observable.combineLatest(
                    streamA,
                    streamB,
                    streamC
                )
            )
            .subscribe(onNext: { valueA, valueB, valueC in
                // This line does not get called
                print("\(valueA) \(valueB) \(valueC)")
            }).disposed(by: bag)
    }
}

let child = Child()

child.streamA.accept("A")
child.streamB.accept("B")
child.streamC.accept("C")
/*
moduleVisibility 
Optional("A") Optional("B") nil
*/

推荐阅读