RxSwift:为什么flatMapLatest从不执行onCompleted()?

时间:2018-08-09 18:48:08

标签: ios swift rx-swift reactivex rx-cocoa

在我的Swift UIViewController中,我尝试订阅变量类型的类成员,通过flatMapLatest调用运行它,然后在所有订阅者上执行flatMapLatest可观察到的onCompleted()调用。但是,虽然调用了onNext(),但是onCompleted()从来没有,而且我不确定为什么。

我的班级成员定义为:

KNNQuery<O> knnq =      
        executor.invokeAll(callables)  //List<Future<KNNQery>>
                .stream() //stream<Future<KNNQuery>>
                .map(future -> {
                    try{
                        return future.get();
                    }catch (Exception e){
                        throw new IllegalStateException(e);
                    }
                 })  
                .reducing(KNNQuery::combine) // add it to combine two KNNQuery instances
                .orElse(null);           

在我的viewDidLoad()方法中,我设置了可观察对象:

private let privateVar = Variable<String>("")

和我的ajaxLoad方法:

let localVar = self.privateVar.asObservable().distinctUntilChanged()

localVar.subscribe(onNext: { [weak self] sent in print("first onNext called") })
        .disposed(by: self.disposeBag)

let mappedVar = localVar.flatMapLatest { self.ajaxLoad(var1: $0) }.share()

mappedVar.subscribe(
  onNext: { [weak self] queryRes in
    print("onNext called!")
  },
  onCompleted: { [weak self] in
    print("onCompleted called!")
  }
)
.disposed(by: self.disposeBag)

我对ReactiveX还是很陌生,所以我可能对Rx生命周期的实际状况有些困惑。为什么可以在flatMapLatest调用中调用onNext而不在onCompleted上调用?任何帮助,将不胜感激。预先感谢!

2 个答案:

答案 0 :(得分:1)

System.out.println(timeLabelDetails);运算符不会发出您在块内返回的任何可见事件的已完成事件。

以下代码清楚地说明了这一点。 flatMap发出元素,然后发出完成事件,该事件不会终止订阅。

.just(_)

实际上,_ = Observable<Int>.interval(1, scheduler: MainScheduler.instance) .debug("before flatmap") .flatMap { .just($0 * 2) } .debug("after flatmap") .subscribe() 仅在解除分配后发射完成。参见source v4.0。 请注意,RxSwift 4中不推荐使用Variable,建议您改用RxCocoa的类似Variable

BehaviorRelay

答案 1 :(得分:0)

因为您说过自己很新,而且有点“朦胧” ...

请记住,只要localVar发生变化,它就会发出一个新值并调用ajaxLoad(var1:)。然后ajaxLoad(var1:)的结果将被推送到您订阅的onNext闭包中。

还请记住,如果Observable发出.completed,则它已经死了。它不再发出其他任何东西。

所以flatMapLatest 无法完成(除非其源完成)。如果这样做了,它将杀死整个管道,并且不会路由localVar的更多更改通过管道,ajaxLoad(var:1)将不会再使用新值再次调用,也不会再推送到订阅的onNext方法。

可以将一系列可观察对象视为一台Rube Goldberg机器,其中completed关闭了该机器,而error则将其破坏了。您唯一应该关闭机器的时间是 source (在这种情况下为localVar)是否已完成发射值或 sink (在这种情况下为目的地) onNext:闭包)不需要任何其他值。