目录

  • 协程基础
    • 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相关推荐

  1. 【Kotlin 协程】Flow 异步流 ② ( 使用 Flow 异步流持续获取不同返回值 | Flow 异步流获取返回值方式与其它方式对比 | 在 Android 中使用 Flow 异步流下载文件 )

    文章目录 一.使用 Flow 异步流持续获取不同返回值 二.Flow 异步流获取返回值方式与其它方式对比 三.在 Android 中 使用 Flow 异步流下载文件 一.使用 Flow 异步流持续获取 ...

  2. 【Kotlin 协程】Flow 异步流 ④ ( 流的构建器函数 | flow 构建器函数 | flowOf 构建器函数 | asFlow 构建器函数 )

    文章目录 一.流的构建器函数 1.flow 构建器 2.flowOf 构建器 3.asFlow 构建器 一.流的构建器函数 1.flow 构建器 在之前的博客 [Kotlin 协程]Flow 异步流 ...

  3. 【Kotlin 协程】Flow 异步流 ⑧ ( 背压概念 | 使用缓冲处理背压问题 | 使用 flowOn 处理背压问题 | 从提高收集元素效率方向解决背压问题 )

    文章目录 一.背压概念 二.使用缓冲处理背压问题 三.使用 flowOn 处理背压问题 四.从提高收集元素效率方向解决背压问题 1.Flow#conflate 代码示例 2.Flow#collectL ...

  4. 【Kotlin 协程】Flow 异步流 ⑤ ( 流的上下文 | 上下文保存 | 查看流发射和收集的协程 | 不能在不同协程中执行流的发射和收集操作 | 修改流发射的协程上下文 | flowOn函数 )

    文章目录 一.流的上下文 1.上下文保存 2.流收集函数原型 3.流发射函数原型 4.代码示例 - 查看流发射和收集的协程 5.代码示例 - 不能在不同协程中执行相同流的发射和收集操作 二.修改流发射 ...

  5. 王学岗Kotlin协程(四)————Flow异步流

    参考文章 异步返回值的多个方案 1,什么时候用flow呢?----kotlin要表示多个值 如何表示多个值?挂起函数可以异步返回单个值,但是如果要异步返回多个计算好的值, 就只能用flow了.其它方案 ...

  6. 大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端

    前言:苟有恒,何必三更眠五更起:最无益,莫过一日曝十日寒. 前言 之前一直想写个 WanAndroid 项目来巩固自己对 Kotlin+Jetpack+协程 等知识的学习,但是一直没有时间.这里重新行 ...

  7. Kotlin 协程Flow主要操作符(一)

    Kotlin 协程Flow主要操作符(一) 1. 主要导包 2. map 转换操作符 3. filter过滤操作符 4. take限长操作符 5. drop丢弃操作符 6. flowOn操作符 7. ...

  8. Kotlin 协程Flow、StateFlow、ShareFlow

    Kotlin 协程Flow.StateFlow.ShareFlow 数据流 数据流以协程为基础构建,可提供多个值.从概念上来讲,数据流是可通过异步方式进行计算处理的一组数据序列.所发出值的类型必须相同 ...

  9. Android Kotlin协程和Retrofit结合使用

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/118085035 本文出自[赵彦军的博客] 往期精彩文章: Kotlin实战指南二十 ...

最新文章

  1. ACR2010_MRI骶髂关节炎症与CTX-II变化以及TNF拮抗剂治疗过程中全身炎症改变相关...
  2. python软件下载安装要钱吗-PyCharm下载和安装详细步骤
  3. android 自定义span_教你自定义android中span
  4. python解释器内建函数002
  5. 第四章 大网高级   NSSA
  6. 团队项目(NABC分析)
  7. 动态规划做多了以后,总结的相关知识
  8. php常用功能代码,10段PHP常用功能代码(1)_PHP教程
  9. PHP实现的服务器端,用PHPStorm实现在本地实时编辑服务器端的代码
  10. 你不知道的思维导图能做的事
  11. 机器学习笔记----(1)什么是机器学习
  12. marven编译时:<pre>错误: 不允许使用自关闭元素</pre>
  13. Python 并口(LPT)打印
  14. Ubuntu(Linux) 磁盘分区方案
  15. 【python量化】用时间卷积神经网络(TCN)进行股价预测
  16. litesql mysql 使用_Mysql 的使用方法
  17. 网络通信中 TCP 产生 RST 的三个条件分析
  18. JAVA设计模式之调停者模式
  19. 订阅内容解码失败(非base64码)_【每日礼包】超杀默示录 密文解码礼包大全
  20. 在线教育行业和产品数据分析报告

热门文章

  1. 扬帆跨境电商:Shopify放量5000W扩大规模
  2. 解决Mac系统下需要每次配置环境的问题
  3. Spring Cloud 教程
  4. Linux-overlay启动挂载代码分析
  5. 制定to-do list的艺术
  6. 怎样快速查询多个天天欧洲物流单号的在途信息
  7. 深度信念网络DBN的一个matlab实例
  8. 全国计算机考试一的书,《全国计算机等级考试全能教程》—甲虎网一站式图书批发平台...
  9. 机器学习之二:回归分析
  10. 04_UUID128修改与广播名