RxJava用例指南

RxJava用例指南

开篇灵魂拷问❓ : 你真的会RxJava吗? 反正我是不会

本文会详细介绍使用场景,不会讲原理,主要参考Github RxRiddle kotlin项目

转换成可观察对象 ⭐️(Riddle1)
Observable.just(value)
变换数据⭐️ (Riddle2)
Observable.just(1,2,3).map { it+1 }.subscribe(::print)
// 结果 2,3,4
过滤数据 ⭐️ (Riddle3)
Observable.just(1,2,3).filter { it % 2 == 0 }.subscribe(::print)
//  结果 2
状态切换 (Riddle4)
val subject = PublishSubject.create<Unit>()
subject.scan(false) { t1, _ -> !t1}.subscribe(::print)
subject.onNext(Unit)  // 结果 true
subject.onNext(Unit) // 结果 false
多个可观察对象合并最新状态⭐️ (Riddle5)
val first = BehaviorSubject.createDefault(0)
val second = BehaviorSubject.createDefault(0)
Observable.combineLatest(first, second,
		BiFunction<Int, Int, Int> { t1, t2 -> t1 + t2 }
		).subscribe(::print)   // 结果 0
fisrt.onNext(3)    // 结果 3
second.onNext(6)    // 结果 9
fisrt.onNext(7)    // 结果 13
并行执行网络请求,再合并结果⭐️ (Riddle6)
//网络请求1   first
//网络请求2   second
Single.zip(first, second, BiFunction<Int, Int, Pair<Int, Int>> { t1, t2 -> t1 to t2})
数据去重 ⭐️ (Riddle7)
Observable.just(1,2,3,1,2,3).distinct().subscribe(::print)   // 结果 1,2,3
延迟⭐️ (Riddle8)
Observable.just(1,2,3).delaySubscription(200,TimeUnit.MILLISECONDS).subscribe(::print)
// 延迟200ms, 返回结果 1,2,3
条件取消⭐️ (Riddle9)

触发器触发时取消,如退出登录时,取消轮询

 val trigger = PublishSubject.create<Unit>()
 val main = Observable.interval(1, SECONDS)
 main.takeUtil(trigger).subcribe(::pirnt)  //间隔一秒输出  1 2 3 4 ...
 trigger.onNext(Unit)  //  停止输出
多个数据打平 ⭐️(Riddle10)

如获取列表后,再请求详情

Observable.just(1,2).flatMap({Observable.just("1","2")}){ t1, t2 -> t1 to t2}
.subcribe { print(it)}
//结果 (1, 1)(1, 2)(2, 1)(2, 2)
点击防抖⭐️ (Riddle11)
// 使用到RxBinding
button.clicks().throttleFirst(300,TimeUnit.MILLISECONDS).subscribe{
	System.out.println("clicked")
}
错误返回默认值 ⭐️ (Riddle12)
Observable.create {
      it.onNext(1)
      it.onNext(2)
      it.onError(RuntimeException())
    })
    .onErrorReturnItem(5 )
    .subcribe(::pirnt)  // 结果  1 2 5
连续相同的去重 (Riddle13)
Observable.just(1, 2, 1, 1, 4, 4, 4, 5, 4)
		  .distinctUntilChanged()
		  .subcribe(::pirnt)  // 结果  1 2 1 4 5 4
重试 (Riddle14)
Single.just(Single.fromCallable {println("hello")}
			 throw UnsupportedOperationException()
			).retry(2) {
        it !is IllegalArgumentException
    }
并行获取 按顺发射 (Riddle15)

如缓存与网络请求, 同时进行操作,按顺序返回

Observable.concatEager(listOf(first,second))
转换,停止之前未完成的 (Riddle16)

map的高级版本,自动抛弃之前未完成的, 搜索框输入

first.switchMapSingle { function.invoke(it) }
懒执行 (Riddle17)

subscribe时候 执行

Observable.fromCallable(function)
source 多选一 ,竞速 (Riddle18)

先返回的作为后续的source, 比如多个服务器地址时,选择网速快的

Observable.ambArray(first,second)
监听器转换成Observable (Riddle19)
Observable.create {
          interaction.listener = it::onNext
          it.setCancellable { interaction.listener = null }

  }
按发射顺序合并 ⭐️(Riddle 20)
first.mergeWith(second)
只取第一个值 ⭐️(Riddle 21)
Observable.just(1, 2, 3).blockingFirst().subscribe(::println) 
//结果 1
分组发射⭐️ (Riddle 22)
Observable.range(0, 10).buffer(2,3).subscribe(::println)  // 发送 1 2 ,跳过第三个
//结果  [0,1] [3,4] [6,7] [9]
类型转换 ⭐️(Riddle 23)
Observable.just<Any>("bar", "foo").cast(String::class.java)
计数 ⭐️(Riddle 24)
Observable.just(Unit, Unit).count().subscribe(::print) 
//结果 2
默认值 (Riddle 25)
Observable.empty<Int>().defaultIfEmpty(5).subscribe(::print) 
//结果5
Observable.just(1, 3).defaultIfEmpty(5).subscribe(::print) 
//结果 1 3
发送延时⭐️ (Riddle 26)
source.delay(300,TimeUnit.MILLISECONDS)
不同阶段调用⭐️(Riddle 27 , 28 ,29 ,30)

如日志打印

source.doOnNext { // whatever action you want }
      .doOnComplete{// whatever action you want }
      .doOnError{// whatever action you want }    
      // doOnComplete doOnError可以合并 doOnTerminate
      .doOnSubscribe{// whatever action you want }

重复发送 (Riddle31)
val subscribeCall = AtomicInteger()
val o = Observable.create<Int> {
      when (subscribeCall.getAndIncrement()) {
        0 -> listOf(1, 2, 3).forEach(it::onNext)
        1 -> listOf(6, 7, 8).forEach(it::onNext)
        2 -> listOf(15, 16).forEach(it::onNext)
      }
      it.onComplete()
    }
o.repeat(3).subscribe(::print)
//结果 1, 2, 3, 6, 7, 8, 15, 16
超时设置 (Riddle32)
timeout(3,TimeUnit.SECONDS)  //超时抛出TimeoutException异常
线程切换 ⭐️(Riddle33 , 34)
val first = Schedulers.from(Executors.newSingleThreadExecutor { Thread(it, "First thread") })
val second = Schedulers.from(Executors.newSingleThreadExecutor { Thread(it, "Second thread") })
  
source.observeOn(first)  //观察线程 下游的都切换到该线程
	  .map{   }
	  .subscribeOn(second) //订阅线程  上下游的都切换到该线程
	  .filter{}
	  .subscirbe()
条件切换发送源 (Riddle35)

如缓存未命中,走网络请求

val first = Maybe.empty<String>()
val second = Single.just("Second")
first.switchIfEmpty(second).subscribe(::print) //结果 Second
防抖操作 ⭐️(Riddle36)
val source = PublishSubject.create<String>()
source.debounce(milliseconds,TimeUnit.MILLISECONDS).subscribe(::print)

source.onNext("1")  
source.onNext("2")
source.onNext("3")

说下throttle /debounce 差异

  • debounce 两次事件间隔时间
  • throttle 两个时间段的间隔时间, 如间隔1s , [0,1] 在0.999s发射 [1,2] 在1.001s发射
异常恢复⭐️(Riddle37)
Observable.concat(Observable.just(true), Observable.error(IOException()))
	.onErrorResumeNext { t: Throwable ->
        when (t) {
            is IOException -> Observable.just(false)
            else -> Observable.error(t)
        }
    }
    .subscribe(::print )
    //结果  true false
双击检测⭐️ (Riddle100)
val source =Observable.fromIterable(listOf(0L, 200L, 400L, 700L, 800L))
        .flatMapSingle { Single.timer(it, MILLISECONDS).map {  } }

source.buffer(300,TimeUnit.MILLISECONDS)
          .filter{it.size >1}
          .map {  }
          .subscribe {println("双击") }
          //结果 输出两次 "双击"   0L, 200L   和  700L, 800L

//可以结合RxBinding使用

button.clicks().buffer(300,TimeUnit.MILLISECONDS)
          .filter{it.size >1}
          .map {  }
          .subscribe {println("双击") }
倒计时⭐️ (Riddle101)
Observable.interval(0,1,TimeUnit.SECONDS)
          .map { 10-it }
          .takeUntil{ it ==0L}
          .subscribe(::println)
        
//结果倒计时  10 9 8 7 6 5 4 3 2 1 0

结尾灵魂拷问❓ : 你真的会RxJava吗? 好像会了一点😙

参考

RxRiddles

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值