Corrutinas de Kotlin: selección de multiplexación ()

1. Concepto

        También llamada expresión de selección, es una función de suspensión que puede esperar múltiples resultados de suspensión al mismo tiempo y solo usar el valor que se recupera más rápido (es decir, obtener datos de múltiples maneras, el que devuelva el resultado más rápido).

        Cuando se alcanza select() al mismo tiempo, la subexpresión se escribirá primero. Si desea que sea aleatorio (justo), use selectUnbiased() para reemplazar.

        Lo que se puede seleccionar es el tipo de función SelectClauseN.

diversión en línea suspendida pública <R> select(constructor en línea cruzada: SelectBuilder<R>.() -> Unidad): R 

interfaz pública sellada SelectBuilder<in R> {

        operador público divertido SelectClause0.invoke(bloque: suspender () -> R)
        operador público divertido <Q> SelectClause1<Q>.invoke(bloque: suspender (Q) -> R)
        operador público divertido <P, Q> SelectClause2<P , Q>.invoke(param: P, block: suspender (Q) -> R)
        operador público divertido <P, Q> SelectClause2<P?, Q>.invoke(block: suspender (Q) -> R): Unidad = invocar (nulo, bloquear)
}

SeleccionarCláusula0 El evento correspondiente no tiene valor de retorno. Por ejemplo trabajo.onJoin.
SeleccionarCláusula1 El evento correspondiente tiene un valor de retorno. Por ejemplo, diferido.onAwait y canal.onReceive.
SeleccionarCláusula2 El evento correspondiente tiene un valor de retorno. Además, se requiere un parámetro adicional, por ejemplo Channel.onSend() tiene dos parámetros, el primero es el valor del tipo de datos del canal que indica el valor a enviar y el segundo es la función de devolución de llamada cuando el envío es exitoso. .

2. uso

En el tipo de retorno Deferred que usa async() para iniciar la corrutina, se define la variable onAwait del tipo de función SelectClause1. Su función es la misma que await(), excepto que cuando se usa como subsentencia en select( ), tiene la función de "esperar a ver quién espera al mismo tiempo". Efecto "Regresar primero". Lo mismo ocurre con otras cosas.

2.1 Multiplexación de múltiples trabajos.onJoin

fun main() = runBlocking<Unit> {
    val job1 = launch {
        delay(100)
        println("job 1")
    }
    val job2 = launch {
        delay(10)
        println("job 2")
    }
    select {
        job1.onJoin { println("job 1 更快") }
        job2.onJoin { println("job 2 更快") }
    }
    delay(1000)
}
//打印:
//job 2
//job 2 更快
//job 1

2.2 Multiplexación múltiple diferida.onAwait

interfaz pública Diferida<out T> : Job {         public val onAwait: SelectClause1<T> //等效await()

fun main() = runBlocking {
    val defferedCache = async {
        delay(10)
        "Cache"
    }
    val defferedLocal = async {
        delay(100)
        "Local"
    }
    val defferedRemote = async {
        delay(1000)
        "Remote"
    }
    val result = select {
        defferedCache.onAwait { println("最快的是$it") }
        defferedLocal.onAwait { println("最快的是$it") }
        defferedRemote.onAwait { println("最快的是$it") }
    }
    delay(2000)
    println(result) //打印:最快的是Cache
}

2.3 Multiplexación de múltiples canales.onReceive

interfaz pública SendChannel<en E> {

        valor público onSend: SelectClause2<E, SendChannel<E>> //Equivalente a send()

}

interfaz pública RecibirCanal<salida E> {

        valor público onReceive: SelectClause1<E> //等效recibir()

        diversión suspendida pública recibirCatching(): ChannelResult<E> //等效receiveCatching()

}

// OnReceive() en select() no se ejecutará en un canal cerrado y provocará que el select() correspondiente arroje una excepción. Utilice onReceiveCatching() para realizar operaciones específicas al cerrar el canal.

suspend fun getDataFromLocal() = withContext(Dispatchers.IO) { "Local" }
suspend fun getDataFromRemote() = withContext(Dispatchers.IO) { "Remote" }

@OptIn(ExperimentalCoroutinesApi::class)
fun main() = runBlocking {
    val produceLocal = produce { send(getDataFromLocal()) }
    val produceRemote = produce { send(getDataFromRemote()) }
    val result = select {
        produceLocal.onReceive { it }
        produceRemote.onReceive { it }
    }
//    val result = select {
//        produceLocal.onReceiveCatching { it.getOrNull() ?: "Channel已关闭:produceLocal" }
//        produceRemote.onReceiveCatching { it.getOrNull() ?: "Channel已关闭:produceRemote " }
//    }
    println("结果更快的是:$result")
}

Supongo que te gusta

Origin blog.csdn.net/HugMua/article/details/132613352
Recomendado
Clasificación