RxJava ignoreElement改造成Completable
这两天被一个RxJava的操作符给坑了,就是ignoreElement()。我们在Post一个请求的时候,例如上传用户信息到API当中。
public Observable<Void> delete(String profileId) {
return accountApi.deleteProfileById(profileId, null)
.ignoreElements();
}
如果这样写的话,会导致上在调用这个delete接口的时候,无法执行**onNext()**里面的逻辑,为什么会这个样子,具体文档里面给的图
很简单明了就可以知道。可以看看ignoreElements这个Operator怎么实现的:
public static <T> OperatorIgnoreElements<T> instance() {
return (OperatorIgnoreElements<T>) Holder.INSTANCE;
}
OperatorIgnoreElements() {
// singleton
}
@Override
public Subscriber<? super T> call(final Subscriber<? super T> child) {
Subscriber<T> parent = new Subscriber<T>() {
@Override
public void onCompleted() {
child.onCompleted();
}
@Override
public void onError(Throwable e) {
child.onError(e);
}
@Override
public void onNext(T t) {
// ignore element
}
};
child.add(parent);
return parent;
}
上面的注释很简单了,已经说明了这个操作符会ignore onNext()。为了便于阅读和编写,我们把上面的API改造成返回Completable。
public Completable delete(String profileId) {
return accountApi.deleteProfileById(profileId, null)
.toCompletable();
}
再来看下Completable的实现:
public static Completable fromObservable(final Observable<?> flowable) {
requireNonNull(flowable);
return create(new OnSubscribe() {
@Override
public void call(final rx.CompletableSubscriber cs) {
Subscriber<Object> subscriber = new Subscriber<Object>() {
@Override
public void onCompleted() {
cs.onCompleted();
}
@Override
public void onError(Throwable t) {
cs.onError(t);
}
@Override
public void onNext(Object t) {
// ignored
}
};
cs.onSubscribe(subscriber);
flowable.unsafeSubscribe(subscriber);
}
});
}
除了没有onNext()&&onSuccess(),Completable其实和Observable的行为大体上相似。具体的可以点击这里。
我是这样理解使用Completable会好于**ignoreElement()**这个操作符的。
- 在一个Post请求中,我们比较关心onCompleted()之后的事情,例如先调用远程API通知服务器删除数据,完了之后再执行本地数据库的删除逻辑。
- 另外通过返回Completable,会避免再上层写逻辑的时候,写了onNext()逻辑,实际上是无法执行的。IDE会检查报错。