Rxjava(过滤类)-Sample

来源:互联网 发布:淘宝上货供货商怎么写 编辑:程序博客网 时间:2024/04/29 03:12

定期发射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);                    }                });

输出:

101010910098100871007610065100541004310032100211001onCompleted

可以看出,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