//1.表示多个值 流用于返回多个异步计算值 fun foo(): List<Int> = listOf(1, 2, 3) fun forEachList() { foo().forEach { value -> println(value) } } //2.序列 fun foos(): Sequence<Int> = sequence {//使用一个序列(Sequence)来表示数字 for (i in 1..3) { Thread.sleep(1000)//等待100毫秒 yield(i)//下一个值 } } fun forEachSequences() { foos().forEach { value -> println(value) } } //3 挂起函数 suspend fun foo_Suspending(): List<Int> {//suspend修饰不会阻塞主线程 ,List<Int>我们只能同时返回所有值 delay(1000) return listOf(1, 2, 3) } fun main_Suspending() = runBlocking { foo_Suspending().forEach { value -> println(value) } } //4.Flows fun foo_flows(): Flow<Int> = flow {//构造器函数名为 flow 不再标记 suspend 修饰符 for (i in 1..3) { //flow{...} 中的代码块可以挂起 delay(2000) emit(i)//值通过 emit 函数从流中发出 } } fun main_flows() = runBlocking<Unit> { launch {//用于检查主线程是否阻塞 for (k in 1..3) { println("k $k") delay(1000)//等待1000毫秒 不会阻塞主线程 } } foo_flows().collect { value -> println("$value") }// collect 函数从 flow 中取值 } //5.流是冷的 fun foo_cold(): Flow<Int> = flow { for (i in 1..3) {//flow 每次收集时都会启动 println("Flow开启") delay(1000) emit(i) } } fun main_cold() = runBlocking { val flows = foo_cold() println("...$flows") flows.collect { value -> println("$value") }//先开启,再打印值 println("...收集") } //6.取消流 fun foo_cancel(): Flow<Int> = flow { for (i in 1..3) { delay(1000) emit(i) } } fun main_cancel() = runBlocking { withTimeoutOrNull(1200) {//运行一个就取消了 foo_cancel().collect { value -> println("$value") } } println("end") } //7.流构建器 asFlow fun main_asFlow() = runBlocking { (1..3).asFlow().collect { value -> println("$value") } } //8.中间流运算符 suspend fun per_request(requst: Int): String { delay(1000) return "$requst" } fun main_map() = runBlocking { (1..3).asFlow()//构建流 .map { request -> per_request(request) }//中间运算符 .collect { value -> println("$value") } } //9.转换操作符 suspend fun per_transform(requst: Int): String { delay(1000) return "$requst" } fun main_transform() = runBlocking { (1..3).asFlow()//构建流 .transform { request -> emit("request $request")//异步请求之前发出一个字符串和跟随一个响应 emit(per_transform(request)) }//中间运算符 .collect { value -> println("$value") } } //10 限长度运算符 fun number(): Flow<Int> = flow { try { emit(1) emit(2) println("end")//运行到这里关闭 emit(3) } finally { println("finally") } } fun main_take() = runBlocking { number().take(2).collect { value -> println("$value") }//take 限制长度 } //11.流运算符 fun main_reduce()= runBlocking { val sun= (1..3).asFlow()//构造流 .map { it*it } .reduce { a, b ->a + b }//转结果为相加 然后返回 println("$sun") } //12 流是连续的 像流水线那样 fun main_flowd() = runBlocking { (1..10).asFlow().filter { println("请求值 $it") it % 2 != 0 } .map { println("返回值是 $it") }.collect { value -> println("$value") } } //13 流上下文保留 也就是经过后 会有值出来 是保存的 fun main_save()= runBlocking { (1..5).asFlow().filter {it%2==0}.map { println("返回值是 $it") }.collect { value -> println("最后返回 $value") } } //14 错误地使用 withContext fun flow_withContext():Flow<Int> = flow { withContext(Dispatchers.Default){//这行报错Flow invariant is violated for (i in 1..3){ emit(i) println("$i") } } } fun main_withContext()= runBlocking { flow_withContext().collect { value -> println("$value") } } //15 flowOn 运算符 不能改变流的上下文 fun log(msg: String) = println("[${Thread.currentThread().name}] $msg") fun flow_flowOn():Flow<Int> = flow { for (i in 1..3){ log("flow_flowOn $i") emit(i) } }.flowOn(Dispatchers.IO)//在子线程执行 fun main_flowOn()= runBlocking { log("主")//主线程执行 flow_flowOn().collect { value -> log("main_flowOn $value") }//主线程执行 } //16 缓冲 减少收集时间 fun flow_buffer():Flow<Int> = flow { for (i in 1..3){ delay(2000)//一共6000 emit(i) } } fun main_buffer() = runBlocking { val time= measureTimeMillis { flow_buffer().buffer(1).collect { value -> delay(300)//这一步收集 只用了300多 println("$value") } } println("所需要的时间 $time")//6326 } //17合并 conflate fun flows_conflate():Flow<Int> = flow { for (i in 1..3){ emit(i) } } fun main_conflate() = runBlocking { flows_conflate().conflate().//第二个数字被合并(丢弃) collect { value -> println("$value") } } //18 处理最新 collectLatest fun flow_collectLatest():Flow<Int> = flow { for (i in 1..3){ emit(i) } } fun main_collectLatest()= runBlocking { flow_collectLatest().collectLatest { value -> delay(300)//延迟3秒 println("$value") }//只打印最后一个 } //19 组合流 zip combine 组合流的作用 val one=(1..2).asFlow() val two= flowOf("4","5","6") fun main_zip() = runBlocking { // one.zip(two){a,b->"$a->$b"}.collect { value -> println("$value") }//不会打印6 one.combine(two){a,b->"$a->$b"}.collect { value -> println("$value") }//2重复 然后跟6一起打印出来 } //20 展平流 // flatMapConcat 等待内部流完成,然后开始收集下一个流 //flatMapMerge 同时收集所有传入流并将其值合并到单个流中,以便尽快发出值 //flatMapLatest 处理最新值 fun flow_Flattening(i: Int):Flow<String> = flow { emit("old $i") delay(1000) emit("new $i") } fun main_Flattening() = runBlocking { val startTime = System.currentTimeMillis() (1..3).asFlow().onEach { delay(100) }.flatMapLatest { flow_Flattening(it) }.collect { value -> println("$value 收集时间 ${System.currentTimeMillis() - startTime} ms ") } } //21 捕获异常流 //sampleStart fun flow_catch(): Flow<String> = flow { for (i in 1..3) { println("Emitting $i") emit(i) // emit next value } } .map { value -> check(value <= 1) { println("$value") }//制造异常 "string $value" } fun main_catch() = runBlocking<Unit> { //1.用try catch // try { // flow_catch().collect { value -> println(value) } // } catch (e: Throwable) { // println("Caught $e")//有异常就捕获 // } //2.catch // flow_catch().catch { e-> emit("Caught $e") }.collect { value -> println("$value") }//用catch替代 //3.异常放在collect 也就是下游 不起作用 flow_catch().catch { e-> emit("Caught $e") }.collect { value -> // check(value <= "1") { "Collected $value" }// println(value) } //4.声明式捕获异常 flow_catch().onEach { value -> check(value <= "1") { "检查 $value" } println(value) } .catch { e -> println("Caught $e") } .collect() }
//22.流完成 除了finally外,还有 onCompletion fun flows_oncompletion():Flow<Int> = flow { emit(1)//发出数字1后引发异常 throw RuntimeException() } fun main_onCompletion() = runBlocking { flows_oncompletion().onCompletion {//onCompletion有个 Throwable 参数可用于确定流收集是正常完成还是异常完成 cause ->if (cause!=null) println("有异常出现") } .catch { //onCompletion 运算符不处理异常 异常仍然会流向下游 cause -> println("异常是 $cause") }.collect { value -> println("$value") } } //23 启动流 fun main_even() = runBlocking { (1..3).asFlow().onEach { delay(1000) }.onEach { event-> println("$event") //将一段代码注册为对传入事件的响应 }.collect( )//等待收集流完成 println("end ..")//等收集完成 才运行这个 } //24 启动流 fun main_launchIn() = runBlocking { (1..3).asFlow().onEach { delay(1000) }.onEach { event-> println("$event") //将一段代码注册为对传入事件的响应 }.launchIn( this)//等待收集流完成 println("end ..")//先运行这个 }