Kotlin Coroutines是一個非常強大的庫,它附帶了許多提供開箱即用功能的API。在本文中,我們將研究其中一個API,即選擇表達式。
什么是選擇表達式???
在應(yīng)用程序開發(fā)過程中,您可能有多個掛起的函數(shù),并且您希望有一個業(yè)務(wù)邏輯,在掛起函數(shù)完成時對其結(jié)果進行操作。協(xié)同程序庫通過select函數(shù)提供此功能。select函數(shù)充當(dāng)類型安全構(gòu)建器,其中提供了可在可掛起函數(shù)上注冊回調(diào)的擴展函數(shù)。
在Kotlin協(xié)同程序中,“select”表達式可以同時等待多個掛起函數(shù),并選擇第一個可用的結(jié)果。它是一個掛起函數(shù),在其中一個子句被選中或失敗之前一直掛起。
選擇表達式可以在應(yīng)用程序開發(fā)過程中的一些用例中使用。例如
- 有一種情況,當(dāng)數(shù)據(jù)“a”或“B”中的任何人首先可用時,您希望處理“X”事件。
- 您正在同時運行一些操作,無論哪個先完成(或返回結(jié)果),都要繼續(xù)執(zhí)行優(yōu)勝者操作的結(jié)果,即數(shù)據(jù)競賽。
…還有很多這樣的用例。
讓我們通過看例子來進一步探討它。
使用它?
正如我們討論的一些用例,使用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>的函數(shù),其中data1需要1000ms來加載數(shù)據(jù),data2需要2000ms。
- 在“select”生成器中,onAwait()子句用于等待結(jié)果。
- 當(dāng)data1()返回結(jié)果時,它的值(“Hello”)被選中,因為它首先完成。因此,它是一個贏家。
讓我們來看另一個例子,在這個例子中,您希望在用戶在UI上執(zhí)行多個選項之間的一些交互之后執(zhí)行某個操作。select表達式可以這樣使用????
suspend fun awaitCloseDialog() {
select<Unit> {
async { dialog.closeButton.awaitClick() }.onAwait { }
async { dialog.okButton.awaitClick() }.onAwait { }
}
dialog.dismiss()
}
在本例中,當(dāng)單擊“關(guān)閉”按鈕或單擊“確定”按鈕時,對話框?qū)⒈魂P(guān)閉。
您還可以從Channel API生成的值中選擇結(jié)果,如下所示????.
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后生成偶數(shù),oddChannel在500ms后生成數(shù)字。因此,您可以看到奇數(shù)比偶數(shù)更容易被選中。
這些是選擇表達式的一些基本示例。
注:當(dāng)可以同時選擇多個子句時,將優(yōu)先選擇執(zhí)行它們的第一個子句,即選擇函數(shù)偏向于第一個子句。使用selectUnbiased在子句中進行無偏選擇,只需對選擇進行洗牌/隨機化。
支持的選擇方法列表
這些API來自協(xié)同程序,受select表達式子句支持。
| Receiver | Suspending function | Select clause |
|---|---|---|
| Job | join | onJoin |
| Deferred | await | onAwait |
| SendChannel | send | onSend |
| ReceiveChannel | receive | onReceive |
| ReceiveChannel | receiveCatching | onReceiveCatching |
| - | delay | onTimeout |
您可以訪問 官方文檔,了解關(guān)于select表達式的更多可用API。
最后的想法??
在Kotlin中開發(fā)應(yīng)用程序時,select表達式可以在許多用例中使用。但請記住,目前這個API是實驗性的,這意味著相應(yīng)聲明的設(shè)計存在一些開放性問題,這些問題可能會(也可能不會)導(dǎo)致未來的更改。
我希望你喜歡這篇文章。如果你覺得這有幫助,請分享這篇文章。
分享就是關(guān)懷!????
Thank you! ??
為了幫助入門學(xué)習(xí)者或想深入的學(xué)習(xí) Kotlin ,在這里分享一份《高級Kotlin強化實戰(zhàn)學(xué)習(xí)手冊(附Demo)》供Android開發(fā)者進階學(xué)習(xí) Kotlin,內(nèi)容涵蓋 Kotlin 入門教程、Kotlin實戰(zhàn)避坑指南、Kotlin Jetpack 實戰(zhàn)三大模塊。希望能幫助到大家學(xué)習(xí)提升,如有需要參考的可以看下面 ↓↓↓
有需要的可以復(fù)制下方鏈接,傳送直達!??!
https://docs.qq.com/doc/DQkdwVlhGS3pURnN1
第一章 Kotlin入門教程
Kotlin 概述
Kotlin 與 Java 比較
巧用 Android Studio
認識 Kotlin 基本類型
走進 Kotlin 的數(shù)組
走進 Kotlin 的集合
集合問題
完整代碼
基礎(chǔ)語法

第二章 Kotlin 實戰(zhàn)避坑指南
方法入?yún)⑹浅A浚豢尚薷?/p>
不要 Companion 、INSTANCE ?
Java 重載,在 Kotlin 中怎么巧妙過渡一下?
Kotlin 中的判空姿勢
Kotlin 復(fù)寫 Java 父類中的方法
Kotlin “狠”起來,連TODO 都不放過!
is、as` 中的坑
Kotlin 中的 Property 的理解
also 關(guān)鍵字
takeIf 關(guān)鍵字
takeIf 關(guān)鍵字
單例模式的寫法

第三章 項目實戰(zhàn)《Kotlin Jetpack 實戰(zhàn)》
從一個膜拜大神的 Demo 開始
Kotlin 寫 Gradle 腳本是一種什么體驗?
Kotlin 編程的三重境界
Kotlin 高階函數(shù)
Kotlin 泛型
Kotlin 擴展
Kotlin 委托
協(xié)程“不為人知”的調(diào)試技巧
圖解協(xié)程:suspend
