Kotlin 协程与flow
目录
- 协程基础
- launch
- suspend
- coroutineScope
- join
- 终结动作
- 超时
- 组合式协程
- async
- Flow
- intellij 配置
- 基础
- flowOn
协程基础
launch
runBlocking 是一个协程生成器,它连接了协程与非协程世界
launch 也是一个协程生成器,它用于开启一个协程
delay 可以挂起协程,直到计时结束才继续运行该协程
// 该协程实现效果:先输出hello,延迟1s后再输出world
fun main() = runBlocking {launch {(1000L)println("world")}println("hello ")
}
suspend
为任意函数添加 suspend 修饰可以将其变成挂起函数
挂起函数可以充当一个协程,并且其内部依然可以使用其他暂停函数(比如 delay)
挂起函数内可以添加携程作用域
fun main() = runBlocking {launch {demo()}println("hello ")
}suspend fun demo(){delay(1000L)println("world")
}
coroutineScope
coroutineScope
定义一个协程作用域
coroutineScope
是挂起而不干扰当前线程其余代码执行,runBlocking 直接阻塞整个线程
挂起函数可以直接使用协程作用域
下方代码中,可见一个协程作用域内可以有多个 launch 实现多协程并发执行
注意到 runBlocking 的阻塞作用,故主线程 main 必须先执行协程 doWorld 完毕后才能打印 println
fun main() = runBlocking {doWorld()println("Done")
}suspend fun doWorld() = coroutineScope {launch {delay(2000L)println("World 2")}launch {delay(1000L)println("World 1")}println("Hello")
}// 运行结果
// Hello
// World 1
// World 2
// Done
join
launch 开启协程返回一个 join 对象,将其传入一个变量并使用 join()方法来启动该协程!
对 job 对象使用 cancel()方法来取消掉协程执行
fun main() = runBlocking {val coroutine = launch {delay(1000L)println(1+1)}coroutine.join()println("协程执行完毕!")
}
终结动作
finally 代码块内容会在协程被取消后立即执行
fun main() = runBlocking {//sampleStartval job = launch {try {repeat(1000) { i ->println("job: I'm sleeping $i ...")delay(500L)}} finally {println("job: I'm running finally")}}delay(1300L) // 延迟一段时间println("main: I'm tired of waiting!")job.cancelAndJoin() // 取消该作业并且等待它结束println("main: Now I can quit.")
//sampleEnd
}// 运行结果
// job: I'm sleeping 0 ...
// job: I'm sleeping 1 ...
// job: I'm sleeping 2 ...
// main: I'm tired of waiting!
// job: I'm running finally
// main: Now I can quit.
超时
使用 withTimeout 定义带超时范围的协程作用域,超时后立即报错
fun main() = runBlocking {withTimeout(1100L){repeat(1000){println("hey!")delay(500L)}}
}
组合式协程
普通顺序调用
定义两个挂起函数,并直接在协程作用域内按顺序调用他们,即可实现组合两个协程
为协程添加 async 可以使其变成异步的
fun main() = runBlocking {val res = measureTimeMillis {val d1 = demo1()val d2 = demo2()println("${d1+d2}")}println("完成啦")
}suspend fun demo1():Int{delay(1000L)return 1
}
suspend fun demo2():Int{delay(1000L)return 100
}
async
这里的异步很类似于 js 中的异步函数,只不过 async 和 await 表达的意思以及使用的场景不太一致而已
fun main() = runBlocking<Unit> {val time = measureTimeMillis {println("${sum()}")}println("所有事都做完了")
}// 将所有挂起函数组合在一个总挂起函数中
// 使用协程作用域coroutineScope
suspend fun sum():Int = coroutineScope {// 每个挂起函数都必须使用async修饰,表示其为异步的val d1 = async { demo1() }val d2 = async { demo2() }// await执行异步函数d1.await()+d2.await()
}suspend fun demo1():Int{delay(1000L)return 1
}
suspend fun demo2():Int{delay(1000L)return 100
}
Flow
intellij 配置
对于 intellij idea 2002 版本及以上的 IDE,都已捆绑 kotlin 插件,无需我们自主安装
但如果我们想要使用 kotlin flow 数据流操作的语法支持的话,依旧需要下载 coroutines-core
依赖
首先去 maven 仓库下载对应 jar 包:下载 1.3.2 版本的 coroutines-core
新建一个项目,项目管理方式 maven 或者 idea 都可以无所谓
依次点击文件->项目结构->模块,选择你要添加依赖的模块
点击绿色加号,选择第一项,导入我们刚刚下载好的 jar 包,然后勾选即可
基础
flow{}
创建新的流
flowOf()
根据已有数据创建流
emit
为流插入一个元素
collect
对流做出的操作(一般均位于结尾被调用)
fun main() = runBlocking {flow {emit(1)emit(2)}.collect {println(it)}
}
asFlow
把已有数据集转换为流
filter
过滤器
take
取出当前链上结果的前 N 个数据
fun main() = runBlocking {(1..10).asFlow() // 将已有数据转换为流.map { it*100 }.filter { it>500 }.take(2).collect { println(it) } // 600 700
}
onStart
流开始前执行
onCompletion
流完成后执行
fun main() = runBlocking {(1..10).asFlow().onStart { println("我准备好了") }.onCompletion { println("我的活干完了") }.collect { println(it) }
}
flowOn
flowOn() 指定协程上游执行所在池
如下代码可知,上游协程执行 map,被显式规定在了 IO 池中,而下游的 collect 部分则依旧在 MAIN 池中
fun main() = runBlocking {(1..2).asFlow().map { println(it) }.flowOn(Dispatchers.IO).collect { println("collect") }
}// 输出结果
// 1
// 2
// collect
// collect
launchIn
即针对下游协程需要用到的 Dispatcher
val customDispatcher:ExecutorCoroutineDispatcher = Executors.newSingleThreadExecutor{Thread(it,"null").apply { isDaemon=true }
}.asCoroutineDispatcher()fun main() = runBlocking {val scope = CoroutineScope(customDispatcher)(1..2).asFlow().map { println(it) }.flowOn(Dispatchers.IO).onEach { println("每次执行弹出") }.launchIn(scope)delay(100)
}
Kotlin 协程与flow相关推荐
- 【Kotlin 协程】Flow 异步流 ② ( 使用 Flow 异步流持续获取不同返回值 | Flow 异步流获取返回值方式与其它方式对比 | 在 Android 中使用 Flow 异步流下载文件 )
文章目录 一.使用 Flow 异步流持续获取不同返回值 二.Flow 异步流获取返回值方式与其它方式对比 三.在 Android 中 使用 Flow 异步流下载文件 一.使用 Flow 异步流持续获取 ...
- 【Kotlin 协程】Flow 异步流 ④ ( 流的构建器函数 | flow 构建器函数 | flowOf 构建器函数 | asFlow 构建器函数 )
文章目录 一.流的构建器函数 1.flow 构建器 2.flowOf 构建器 3.asFlow 构建器 一.流的构建器函数 1.flow 构建器 在之前的博客 [Kotlin 协程]Flow 异步流 ...
- 【Kotlin 协程】Flow 异步流 ⑧ ( 背压概念 | 使用缓冲处理背压问题 | 使用 flowOn 处理背压问题 | 从提高收集元素效率方向解决背压问题 )
文章目录 一.背压概念 二.使用缓冲处理背压问题 三.使用 flowOn 处理背压问题 四.从提高收集元素效率方向解决背压问题 1.Flow#conflate 代码示例 2.Flow#collectL ...
- 【Kotlin 协程】Flow 异步流 ⑤ ( 流的上下文 | 上下文保存 | 查看流发射和收集的协程 | 不能在不同协程中执行流的发射和收集操作 | 修改流发射的协程上下文 | flowOn函数 )
文章目录 一.流的上下文 1.上下文保存 2.流收集函数原型 3.流发射函数原型 4.代码示例 - 查看流发射和收集的协程 5.代码示例 - 不能在不同协程中执行相同流的发射和收集操作 二.修改流发射 ...
- 王学岗Kotlin协程(四)————Flow异步流
参考文章 异步返回值的多个方案 1,什么时候用flow呢?----kotlin要表示多个值 如何表示多个值?挂起函数可以异步返回单个值,但是如果要异步返回多个计算好的值, 就只能用flow了.其它方案 ...
- 大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端
前言:苟有恒,何必三更眠五更起:最无益,莫过一日曝十日寒. 前言 之前一直想写个 WanAndroid 项目来巩固自己对 Kotlin+Jetpack+协程 等知识的学习,但是一直没有时间.这里重新行 ...
- Kotlin 协程Flow主要操作符(一)
Kotlin 协程Flow主要操作符(一) 1. 主要导包 2. map 转换操作符 3. filter过滤操作符 4. take限长操作符 5. drop丢弃操作符 6. flowOn操作符 7. ...
- Kotlin 协程Flow、StateFlow、ShareFlow
Kotlin 协程Flow.StateFlow.ShareFlow 数据流 数据流以协程为基础构建,可提供多个值.从概念上来讲,数据流是可通过异步方式进行计算处理的一组数据序列.所发出值的类型必须相同 ...
- Android Kotlin协程和Retrofit结合使用
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/118085035 本文出自[赵彦军的博客] 往期精彩文章: Kotlin实战指南二十 ...
最新文章
- ACR2010_MRI骶髂关节炎症与CTX-II变化以及TNF拮抗剂治疗过程中全身炎症改变相关...
- python软件下载安装要钱吗-PyCharm下载和安装详细步骤
- android 自定义span_教你自定义android中span
- python解释器内建函数002
- 第四章 大网高级 NSSA
- 团队项目(NABC分析)
- 动态规划做多了以后,总结的相关知识
- php常用功能代码,10段PHP常用功能代码(1)_PHP教程
- PHP实现的服务器端,用PHPStorm实现在本地实时编辑服务器端的代码
- 你不知道的思维导图能做的事
- 机器学习笔记----(1)什么是机器学习
- marven编译时:<pre>错误: 不允许使用自关闭元素</pre>
- Python 并口(LPT)打印
- Ubuntu(Linux) 磁盘分区方案
- 【python量化】用时间卷积神经网络(TCN)进行股价预测
- litesql mysql 使用_Mysql 的使用方法
- 网络通信中 TCP 产生 RST 的三个条件分析
- JAVA设计模式之调停者模式
- 订阅内容解码失败(非base64码)_【每日礼包】超杀默示录 密文解码礼包大全
- 在线教育行业和产品数据分析报告