Kotlin Coroutines是一个非常强大的库,它附带了许多提供开箱即用功能的API。在本文中,我们将研究其中一个API,即选择表达式。
什么是选择表达式?🤨
在应用程序开发过程中,您可能有多个挂起的函数,并且您希望有一个业务逻辑,在挂起函数完成时对其结果进行操作。协同程序库通过select函数提供此功能。select函数充当类型安全构建器,其中提供了可在可挂起函数上注册回调的扩展函数。
在Kotlin协同程序中,“select”表达式可以同时等待多个挂起函数,并选择第一个可用的结果。它是一个挂起函数,在其中一个子句被选中或失败之前一直挂起。
选择表达式可以在应用程序开发过程中的一些用例中使用。例如
- 有一种情况,当数据“a”或“B”中的任何人首先可用时,您希望处理“X”事件。
- 您正在同时运行一些操作,无论哪个先完成(或返回结果),都要继续执行优胜者操作的结果,即数据竞赛。
…还有很多这样的用例。
让我们通过看例子来进一步探讨它。
使用它✨
正如我们讨论的一些用例,使用select的非常简单的例子可以是这样的👇🏻.
fun main() = runBlocking<Unit> {
val winner = select<String> {
data1().onAwait { it }
data2().onAwait { it }
}
println("The winner = $winner") // prints "The winner = Hello"
}
fun data1() = GlobalScope.async {
delay(1000)
"Hello"
}
fun data2() = GlobalScope.async {
delay(2000)
"World"
}
在此示例中:
- data1()和data2()是返回Deferred<String>的函数,其中data1需要1000ms来加载数据,data2需要2000ms。
- 在“select”生成器中,onAwait()子句用于等待结果。
- 当data1()返回结果时,它的值(“Hello”)被选中,因为它首先完成。因此,它是一个赢家。
让我们来看另一个例子,在这个例子中,您希望在用户在UI上执行多个选项之间的一些交互之后执行某个操作。select表达式可以这样使用👇🏻
suspend fun awaitCloseDialog() {
select<Unit> {
async { dialog.closeButton.awaitClick() }.onAwait { }
async { dialog.okButton.awaitClick() }.onAwait { }
}
dialog.dismiss()
}
在本例中,当单击“关闭”按钮或单击“确定”按钮时,对话框将被关闭。
您还可以从Channel API生成的值中选择结果,如下所示👇🏻.
fun main() = runBlocking<Unit> {
repeat(5) {
val number = select<Int> {
evenChannel.onReceive { it }
oddChannel.onReceive { it }
}
println(number) // prints "0 1 3 2 5"
}
}
val evenChannel = GlobalScope.produce<Int> {
repeat(10) {
delay(1000)
if (it % 2 == 0) {
send(it)
}
}
}
val oddChannel = GlobalScope.produce<Int> {
repeat(10) {
delay(500)
if (it % 2 != 0) {
send(it)
}
}
}
在本例中,evenChannel在1000ms后生成偶数,oddChannel在500ms后生成数字。因此,您可以看到奇数比偶数更容易被选中。
这些是选择表达式的一些基本示例。
注:当可以同时选择多个子句时,将优先选择执行它们的第一个子句,即选择函数偏向于第一个子句。使用selectUnbiased在子句中进行无偏选择,只需对选择进行洗牌/随机化。
支持的选择方法列表
这些API来自协同程序,受select表达式子句支持。
Receiver | Suspending function | Select clause |
---|---|---|
Job | join | onJoin |
Deferred | await | onAwait |
SendChannel | send | onSend |
ReceiveChannel | receive | onReceive |
ReceiveChannel | receiveCatching | onReceiveCatching |
- | delay | onTimeout |
您可以访问 官方文档,了解关于select表达式的更多可用API。
最后的想法🧐
在Kotlin中开发应用程序时,select表达式可以在许多用例中使用。但请记住,目前这个API是实验性的,这意味着相应声明的设计存在一些开放性问题,这些问题可能会(也可能不会)导致未来的更改。
我希望你喜欢这篇文章。如果你觉得这有帮助,请分享这篇文章。
分享就是关怀!🫶🏻
Thank you! 😃
为了帮助入门学习者或想深入的学习 Kotlin ,在这里分享一份《高级Kotlin强化实战学习手册(附Demo)》供Android开发者进阶学习 Kotlin,内容涵盖 Kotlin 入门教程、Kotlin实战避坑指南、Kotlin Jetpack 实战三大模块。希望能帮助到大家学习提升,如有需要参考的可以看下面 ↓↓↓
有需要的可以复制下方链接,传送直达!!!
https://docs.qq.com/doc/DQkdwVlhGS3pURnN1
第一章 Kotlin入门教程
Kotlin 概述
Kotlin 与 Java 比较
巧用 Android Studio
认识 Kotlin 基本类型
走进 Kotlin 的数组
走进 Kotlin 的集合
集合问题
完整代码
基础语法
第二章 Kotlin 实战避坑指南
方法入参是常量,不可修改
不要 Companion 、INSTANCE ?
Java 重载,在 Kotlin 中怎么巧妙过渡一下?
Kotlin 中的判空姿势
Kotlin 复写 Java 父类中的方法
Kotlin “狠”起来,连TODO 都不放过!
is、as` 中的坑
Kotlin 中的 Property 的理解
also 关键字
takeIf 关键字
takeIf 关键字
单例模式的写法
第三章 项目实战《Kotlin Jetpack 实战》
从一个膜拜大神的 Demo 开始
Kotlin 写 Gradle 脚本是一种什么体验?
Kotlin 编程的三重境界
Kotlin 高阶函数
Kotlin 泛型
Kotlin 扩展
Kotlin 委托
协程“不为人知”的调试技巧
图解协程:suspend