仅为flow的部分测试代码记录 @Test fun testFlow() = runBlocking { flow { for (i in 1..5) { emit(i) delay(1000) } }.collect { println("show $it ${System.currentTimeMillis()}") } } @Test fun testFlow2() { flow { for (i in 1..5) { emit(i) delay(1000) } }.onEach { println("show $it ${System.currentTimeMillis()}") }.onCompletion { println("onCompletion") }.launchIn(GlobalScope) } @Test fun testFlow3() { runBlocking { flow { for (i in 1..5) { emit(i) delay(1000) } }.onEach { println("show $it ${System.currentTimeMillis()}") }.collect { println(it) } } } /** * debounce 限流功能 */ @Test fun testFlow4() { runBlocking { flow { emit(1) delay(100) emit(2) delay(200) emit(3) delay(500) emit(4) delay(1000) emit(5) delay(1200) }.debounce { 1000 }.buffer().collect { println(it) } } } /** * sample操作符 * 规定时间内只发送一个数据 */ @Test fun testFlow5() { runBlocking { flow { repeat(4) { emit(it) delay(50) } }.sample(100).collect { println(it) } } } /** * buffer * 具有缓冲功能,上游结束后下游开始接受数据 */ @Test fun testFlow6() { // runBlocking { // flowOf("a","b","c","d") // .onEach { println(it) } // .collect { println(it) } // } runBlocking { flowOf("a", "b", "c", "d") .onEach { println("1 $it") } .buffer() .collect { println("2 $it") } } } /** * 对flow数据进行filter/map等操作 */ @Test fun testFlow7() { var flows = flow { for (i in 1..10) { delay(100) emit(i) } } runBlocking { val startTime = System.currentTimeMillis() flows.filter { it % 2 == 0 } .map { it * it } .collect { println(it) } println("Time : ${System.currentTimeMillis() - startTime}") } } /** * retry * 发生异常后会再尝试N次,注意避免造成死循环 */ @Test fun testFlow8() { runBlocking { flow { emit(1) emit(2) throw RuntimeException("oops") }.retry(2) .catch { e -> println(e.message) } .collect { println(it) } } } /** * transform * 可以对数据进行装饰 * map内部封装了transform,不需要再发射 */ @Test fun testFlow9() { runBlocking { flow { emit("hello world ${Thread.currentThread()}") }.transform { emit("$it 1") } .transform { emit("$it 2") } .transform { emit("$it 3") } .map { "$it 4" } .collect { println(it) } } } /** * conflate * 上游新数据会覆盖掉旧数据 * 相当于用了buffer操作符,该buffer只能容纳一个数据, */ @Test fun testFlow10() { runBlocking { flow { repeat(4) { emit(it) delay(100) } }.conflate().collect { delay(500) println(it) } } } /** * flowOn * 切换协程和线程 */ @Test fun testFlow11() { runBlocking { flow { emit("Thread : ${Thread.currentThread()}") emit("hello world") }.flowOn(Dispatchers.IO) .collect { println("$it") println("collect ${Thread.currentThread()}") } } } /** * collectLatest操作符 * 若是collect收集比较慢,下一个数据emit过来后会取消未处理的数据 * 原理是基于ChannelFlow * 场景:下载进度 * transformLatest、mapLatest 类似原理 */ @Test fun testFlow12() { runBlocking { flow { repeat(100){ emit(it + 1) } }.collectLatest{ delay(10) println("progress $it") } } }
kotlin之flow操作符学习记录
最新推荐文章于 2024-07-24 22:02:36 发布