如何在Observable为空或null时终止RxJava链式处理?
如果你希望当源Observable是空(Observable.empty())时,整个操作链完全不执行任何操作(包括不触发onComplete回调),有几个简单的方案可以实现:
方案1:使用switchIfEmpty切换到Observable.never()
这是最直接的方式。Observable.never()是一个不会发射任何事件(包括onNext、onError、onComplete)的Observable,所以当源为空时,用它来替代,就能让整个链“静默”下来:
yourServiceObservable // 当源为空时,切换到永远不会发射事件的Observable .switchIfEmpty(Observable.never()) // 你的后续操作符链 .map(data -> processYourData(data)) .doOnNext(result -> saveResult(result)) .subscribe( result -> handleSuccess(result), error -> handleError(error), () -> handleComplete() // 源为空时,这个回调永远不会被触发 );
原理:当源是Observable.empty()时,switchIfEmpty会触发,用never()替换原Observable,而never()不会触发任何订阅回调,所以后续所有操作符都不会执行,完全符合你“不执行任何操作”的需求。
方案2:提前判断是否为空,避免后续订阅
如果你不想修改原操作链,也可以先判断源Observable是否为空,再决定是否执行后续操作:
yourServiceObservable .isEmpty() .subscribe(isEmpty -> { if (!isEmpty) { // 只有当源不为空时,才执行后续操作链 yourServiceObservable .map(data -> processYourData(data)) .doOnNext(result -> saveResult(result)) .subscribe( result -> handleSuccess(result), error -> handleError(error) ); } // 为空时什么都不做 });
注意:这种方式会两次订阅源Observable,如果源是冷Observable(比如每次订阅都会重新发起请求),可能会导致重复请求,所以如果你的源是冷Observable,建议用方案1,或者先把源转成热Observable(比如用cache())再处理。
额外说明:默认行为的小细节
其实默认情况下,Observable.empty()只会触发onComplete回调,不会执行map、doOnNext等依赖onNext事件的操作符。如果你只是不想执行这些操作符的逻辑,而不介意onComplete被触发,那其实不需要额外处理——因为空Observable本来就不会触发这些操作。但如果连onComplete的回调逻辑也不想执行,那方案1就是最佳选择。
内容的提问来源于stack exchange,提问作者hans

