Rxjava2 Observable的数据过滤详解及实例(一)

本文深入解析RxJava2中用于数据过滤的Debounce、Throttle与Sample操作符,包括防抖、限流和稀疏序列的方法,如debounce()、throttleFirst()、throttleLast()、sample()等,适用于优化数据处理和响应速度。
摘要由CSDN通过智能技术生成

简要:

需求了解:

对于数据的观察以及处理过程中往往有需要过滤一些不需要的数据的需求,比如防抖(防止快速操作),获取第一项、指定序列项或者最后一项的需要,获取指定时间内的有效数据等。Rx中提供了丰富的数据过滤处理的操作方法。

可用于过滤和选择Observable发射的数据序列的方法:

  • Debounce:过滤发射速率较快的数据项,防抖操作。
  • Throttle: 对数据序列进行限流操作,可以指定获取周期内的指定数据项,也可以用于防抖。
  • Sample: 允许通过将序列划分为时间片段收集数据,并从每片中取出一个值来稀疏序列。
  • Distinct: 过滤掉重复数据。
  • Skip: 跳过指定的N项数据。
  • Filter: 通过函数指定过滤的数据。
  • First: 只发射第一项或者满足某个条件的第一项数据。
  • Single: 与 first 类似,但是如果原始Observable在完成之前不是正好发射一次数据,它会抛出一个NoSuchElementException 的异常通知。
  • ElementAt: 获取原始Observable发射的数据序列指定索引位置的数据项,然后当做自己的唯一数据发射。
  • ignoreElements: 不发射任何数据,只发射Observable的终止通知。
  • Last: 只发射最后一项(或者满足某个条件的最后一项)数据。
  • Take: 只返回Observable发送数据项序列前面的N项数据,忽略剩余的数据。
  • TakeLast: 只发射Observable发送数据项序列的后N项数据,忽略其他数据。
  • ofType: 过滤一个Observable只返回指定类型的数据。

1. Debounce

仅在过了一段指定的时间还没发射数据时才发射一个数据。Debounce 操作符会过滤掉发射速率过快的数据项。

提示: 操作默认在 computation 调度器上执行,但是你可以指定其它的调度器。

1.1 debounce(timeout, unit)

指定每个数据发射后在 timeout 时间内,原始数据序列中没有下一个数据发射时,发射此项数据,否则丢弃这项数据。此操作与 throttleWithTimeout 方法相同。

注意: 这个操作符会在原始数据的 onCompleted 时候直接发射发射数据,不会因为限流而丢弃数据。

img-debounce(timeout, unit)

实例代码:

	 // 1. debounce(long timeout, TimeUnit unit)
	 // 发送一个数据,如果在包含timeout时间内,没有第二个数据发射,那么就会发射此数据,否则丢弃此数据
	Observable.create(new ObservableOnSubscribe<Integer>() {
   

		@Override
		public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
   
			emitter.onNext(1);	// 下一个数据到此数据发射,	30 < timeout	--> skip			
			Thread.sleep(30);
			emitter.onNext(2); 	// 下一个数据到此数据发射,	100 > timeout	--> deliver
			Thread.sleep(100);
			emitter.onNext(3); 	// 下一个数据到此数据发射,	50 = timeout	--> skip: 			
			Thread.sleep(50);
			emitter.onNext(4); 	// 下一个数据到此数据发射,	onCompleted		--> deliver
			emitter.onComplete();

		}
	}).debounce(50, TimeUnit.MILLISECONDS)	// 指定防抖丢弃时间段为50毫秒
	//  .debounce(50, TimeUnit.MILLISECONDS, Schedulers.trampoline())	// 指定调度为当前线程排队
		.subscribe(new Consumer<Integer>() {
   

			@Override
			public void accept(Integer t) throws Exception {
   
				System.out.println("--> accept debounce(1-1): " + t);
			}
		});

输出:

--> accept debounce(1-1): 2
--> accept debounce(1-1): 4

Javadoc: debounce(timeout, unit)
Javadoc: debounce(timeout, unit, scheduler)

1.2 debounce(debounceSelector)

原始数据发射每一个序列都通过绑定监听debounceSelector的数据通知,在debounceSelector数据发送前,如果有下一个数据,则丢弃当前项数据,继续监视下一个数据。

注意: 这个操作符会在原始数据的 onCompleted 时候直接发射发射数据,不会因为限流而丢弃数据。

img-debounce(debounceSelector)

实例代码:

	// 2. debounce(debounceSelector)
	// 原始数据发射每一个序列的通过监听debounceSelector的数据通知,
	// 在debounceSelector数据发送前,如果有下一个数据,则丢弃当前项数据,继续监视下一个数据
	Observable.create(new ObservableOnSubscribe<Integer>() {
   

		@Override
		public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
   
			emitter.onNext(1);		// skip		--> debounceSelector is no emitter(<2s)
			Thread.sleep(1000);	
			emitter.onNext(2);		// skip		--> debounceSelector is no emitter(<2s)
			Thread.sleep(200);
			emitter.onNext(3);		// deliver	--> debounceSelector is emitter(>2s)
			Thread.sleep(2500);
			emitter.onNext(4);		// skip		--> debounceSelector is no emitter(=2s)
			Thread.sleep(2000);
			emitter.onNext(5);		// deliver	--> onComplete
			Thread.sleep(500);
			emitter.onComplete();
		}
	}).debounce(new Function<Integer, ObservableSource<Long>>() {
   

			@Override
			public ObservableSource<Long> apply(Integer t) throws Exception {
   
				System.out.println("--> apply(1-2): " + t);
				// 设置过滤延迟时间为2秒,此时返回的Observable从订阅到发送数据时间段即为timeout
				return Observable.timer(2, TimeUnit.SECONDS)
						.doOnSubscribe(new Consumer<Disposable>() {
   

							@Override
							public void accept(Disposable t) throws Exception {
   
								// 开始订阅,监听数据的发送来过滤数据
								System.out.println("--> debounceSelector(1-2) is onSubscribe!");
							}
						}).doOnDispose(new Action() {
   
		
							@Override
							public void run() throws Exception {
   
								// 发射数据后,丢弃当前的数据,解除当前绑定
								System.out.println("--> debounceSelector(1-2) is unSubscribe!");
							
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值