Rxjava(过滤类)-take

只发射前面的N项数据


demo

 Observable.range(1, 10).take(2).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });

输出:

1
2


看下take接口

    public final Observable<T> take(final int count) {
        return lift(new OperatorTake<T>(count));
    }

我们看下OperatorTake

public final class OperatorTake<T> implements Operator<T, T> {

    final int limit;

    public OperatorTake(int limit) {
        if (limit < 0) {
            throw new IllegalArgumentException("limit >= 0 required but it was " + limit);
        }
        this.limit = limit;
    }

    @Override
    public Subscriber<? super T> call(final Subscriber<? super T> child) {
        final Subscriber<T> parent = new Subscriber<T>() {

            int count;
            boolean completed;

            @Override
            public void onCompleted() {
                if (!completed) {
                    completed = true;
                    child.onCompleted();
                }
            }

            @Override
            public void onError(Throwable e) {
                if (!completed) {
                    completed = true;
                    try {
                        child.onError(e);
                    } finally {
                        unsubscribe();
                    }
                }
            }

            @Override
            public void onNext(T i) {
                if (!isUnsubscribed() && count++ < limit) {
                    boolean stop = count == limit;
                    child.onNext(i);
                    if (stop && !completed) {
                        completed = true;
                        try {
                            child.onCompleted();
                        } finally {
                            unsubscribe();
                        }
                    }
                }
            }

            /**
             * We want to adjust the requested values based on the `take` count.
             */
            @Override
            public void setProducer(final Producer producer) {
                child.setProducer(new Producer() {

                    // keeps track of requests up to maximum of `limit`
                    final AtomicLong requested = new AtomicLong(0);

                    @Override
                    public void request(long n) {
                        if (n >0 && !completed) {
                            // because requests may happen concurrently use a CAS loop to
                            // ensure we only request as much as needed, no more no less
                            while (true) {
                                long r = requested.get();
                                long c = Math.min(n, limit - r);
                                if (c == 0) {
                                    break;
                                } else if (requested.compareAndSet(r, r + c)) {
                                    producer.request(c);
                                    break;
                                }
                            }
                        }
                    }
                });
            }

        };

        if (limit == 0) {
            child.onCompleted();
            parent.unsubscribe();
        }

        /*
         * We decouple the parent and child subscription so there can be multiple take() in a chain such as for
         * the groupBy Observer use case where you may take(1) on groups and take(20) on the children.
         *
         * Thus, we only unsubscribe UPWARDS to the parent and an onComplete DOWNSTREAM.
         *
         * However, if we receive an unsubscribe from the child we still want to propagate it upwards so we
         * register 'parent' with 'child'
         */
        child.add(parent);

        return parent;
    }

}
在onNext中,如果当前数量未超过limit,则调用onNext,这样就去前面几个

如果达到limit,则调用onComplete

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值