探索Kotlin協(xié)同程序的“select”表達

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容