Rxjava(过滤类)-Sample

定期发射Observable最近发射的数据项


demo

 Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                try {
                    int i = 10;
                    while (i > 0) {
                        subscriber.onNext(i);

                        Thread.sleep(701);
                        subscriber.onNext(i + 100);
                        Thread.sleep(600);
                        subscriber.onNext(i + 1000);
                        Thread.sleep(800);
                        i--;
                    }
                    System.out.println("onCompleted");

                    subscriber.onCompleted();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        })
                .sample(700, TimeUnit.MILLISECONDS)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        System.out.println(integer);
                    }
                });

输出:

10
1010
9
1009
8
1008
7
1007
6
1006
5
1005
4
1004
3
1003
2
1002
1
1001
onCompleted

可以看出,sample也是输出最新的值

我们看sample的代码

 public final Observable<T> sample(long period, TimeUnit unit) {
        return sample(period, unit, Schedulers.computation());
    }
    public final Observable<T> sample(long period, TimeUnit unit, Scheduler scheduler) {
        return lift(new OperatorSampleWithTime<T>(period, unit, scheduler));
    }
这里创建OperatorSampleWithTime

public final class OperatorSampleWithTime<T> implements Operator<T, T> {
    final long time;
    final TimeUnit unit;
    final Scheduler scheduler;

    public OperatorSampleWithTime(long time, TimeUnit unit, Scheduler scheduler) {
        this.time = time;
        this.unit = unit;
        this.scheduler = scheduler;
    }

    @Override
    public Subscriber<? super T> call(Subscriber<? super T> child) {
        final SerializedSubscriber<T> s = new SerializedSubscriber<T>(child);
        final Worker worker = scheduler.createWorker();
        child.add(worker);

        SamplerSubscriber<T> sampler = new SamplerSubscriber<T>(s);
        child.add(sampler);
        worker.schedulePeriodically(sampler, time, time, unit);

        return sampler;
    }
    /**
     * The source subscriber and sampler.
     */
    static final class SamplerSubscriber<T> extends Subscriber<T> implements Action0 {
        private final Subscriber<? super T> subscriber;
        /** Indicates that no value is available. */
        private static final Object EMPTY_TOKEN = new Object();
        /** The shared value between the observer and the timed action. */
        final AtomicReference<Object> value = new AtomicReference<Object>(EMPTY_TOKEN);

        public SamplerSubscriber(Subscriber<? super T> subscriber) {
            this.subscriber = subscriber;
        }

        @Override
        public void onStart() {
            request(Long.MAX_VALUE);
        }

        @Override
        public void onNext(T t) {
            value.set(t);
        }

        @Override
        public void onError(Throwable e) {
            subscriber.onError(e);
            unsubscribe();
        }

        @Override
        public void onCompleted() {
            emitIfNonEmpty();
            subscriber.onCompleted();
            unsubscribe();
        }

        @Override
        public void call() {
            emitIfNonEmpty();
        }

        private void emitIfNonEmpty() {
            Object localValue = value.getAndSet(EMPTY_TOKEN);
            if (localValue != EMPTY_TOKEN) {
                try {
                    @SuppressWarnings("unchecked")
                    T v = (T)localValue;
                    subscriber.onNext(v);
                } catch (Throwable e) {
                    Exceptions.throwOrReport(e, this);
                }
            }
        }
    }
}
可以看到,在call里面启动schedulePeriodically

然后在 onNext里面

        public void onNext(T t) {
            value.set(t);
        }
当定期时间到达时,调用call

       public void call() {
            emitIfNonEmpty();
        }
private void emitIfNonEmpty() {
            Object localValue = value.getAndSet(EMPTY_TOKEN);
            if (localValue != EMPTY_TOKEN) {
                try {
                    @SuppressWarnings("unchecked")
                    T v = (T)localValue;
                    subscriber.onNext(v);
                } catch (Throwable e) {
                    Exceptions.throwOrReport(e, this);
                }
            }
        }

onNext会设置值,而在周期到达时,获取这个值,调用onNext


这里跟debound的区别是这里在call启动的是一个周期回调,而debound是在onNext启动一个超时回调




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值