[英]RxSwift: Why does flatMapLatest never execute onCompleted()?
[英]RxSwift flatMapLatest without disposing previous observables
我正在从以下位置使用RxSwift游乐场: https : //github.com/ReactiveX/RxSwift
我实现了以下示例代码来建模一个简单的异步任务,将一个Observable of Int转换为一个Observable of String:
let pubishSubject = PublishSubject<Int>()
pubishSubject.asObservable()
.debug("before")
.flatMap ({ (value) -> Observable<String> in
let task: Observable<String> = Observable.create { observer in
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
print("Executed \(value)")
observer.on(.next("Async \(value)"))
observer.on(.completed)
})
return Disposables.create(with: {
print("Disposed \(value)")
})
}
return task
})
.debug("after")
.subscribe()
pubishSubject.onNext(1)
pubishSubject.onNext(2)
pubishSubject.onNext(3)
调试输出:
2018-06-01 14:08:35.748: after -> subscribed
2018-06-01 14:08:35.749: before -> subscribed
2018-06-01 14:08:35.751: before -> Event next(1)
2018-06-01 14:08:35.753: before -> Event next(2)
2018-06-01 14:08:35.753: before -> Event next(3)
Executed 1
2018-06-01 14:08:36.785: after -> Event next(Async 1)
Disposed 1
Executed 2
2018-06-01 14:08:36.786: after -> Event next(Async 2)
Disposed 2
Executed 3
2018-06-01 14:08:36.787: after -> Event next(Async 3)
Disposed 3
我需要完成所有异步任务才能继续进行,这工作正常,但是我只需要订阅最新结果(异步3)。
我不能使用flatMapLastest运算符,因为它将取消/处置以前的异步调用。
我不知道如何实现这一目标,我感觉自己被完全封锁了,也许我可以为此使用一个简单的RxSwift运算符,或者我需要以某种方式拆分序列。
我希望有人对实现该目标有一个想法,可以对我有所帮助,非常感谢。
编辑:对我来说,它看起来更像一个队列实现,只要新的Int值在PublishSubject上发布并且仍然有异步任务在运行,它应该跳过所有中间结果,并根据最后发出的Int返回最后一个结果
我在RxJava中有一个解决方案。 转换为RxSwift应该很简单。
使用switchMap()
运算符可连续切换到最新发射。 为了完成以前的排放,您需要订阅它们,并排放值。 为此,请使用publish()
运算符:
@Test
public void testSwitchMap() throws Exception {
PublishSubject<Integer> source = PublishSubject.create();
source
.doOnNext( v -> logger.debug( "emission: {}", v ) )
.switchMap( v -> Observable.just( v )
.delay( 100, TimeUnit.MILLISECONDS )
.publish( s -> {
s.subscribe();
return s;
} ) )
.subscribe( v -> logger.debug( "end result {}", v ) );
source.onNext( Integer.valueOf( 1 ) );
source.onNext( Integer.valueOf( 2 ) );
source.onNext( Integer.valueOf( 3 ) );
Thread.sleep( 1_000 );
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.