这两天被一个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会检查报错。