Android

Separando a produção da emissão com um canal

O texto explica como um canal permite que valores criados em corrotinas diferentes sejam enviados e recebidos de forma segura dentro da estrutura Flow, mantendo a consistência do fluxo. Um exemplo demonstra como várias corrotinas podem preparar valores e enviar para o canal, enquanto a coleta dos valores ocorre na mesma corrotina que executa o collect(), garantindo a segurança da emissão.

Compartilhar
Medium

2. Separando a produção da emissão com um canal

O Flow exige que o emit() seja executado na corrotina que executa collect(). Quando valores são criados em outras corrotinas, precisamos de uma maneira segura para retornar esses valores à corrotina coletora sem violar essa regra. Um canal nos dá essa possibilidade. Uma corrotina pode enviar valores no canal e outra corrotina pode recebê-los. Se o lado receptor rodar dentro do bloco flow { }, o emit() permanece na posição correta e o comportamento do Flow é mantido consistente.

A ideia pode ser demonstrada com um pequeno exemplo. Dentro do bloco flow { } criamos um canal e lançamos várias corrotinas que preparam valores e os enviam no canal. O loop que recebe valores do canal roda na mesma corrotina que executa collect(), então pode chamar o emit() de forma segura.

@OptIn(ExperimentalCoroutinesApi::class)
fun diyChannelFlow(): Flow<Int> = flow {
coroutineScope {
val channel = produce<Int> {
launch {
delay(100)
send(1)
}
launch {
delay(100)
send(2)
}
}

for (value in channel) {
emit(value)
}
}
}

Se coletarmos este fluxo:

diyChannelFlow().collect { value ->
println("Collected: $value")
}

a saída será:

Collected: 1
Collected: 2

A ordem dos valores depende da agendamento. Ambos os valores são preparados em paralelo, então ou 1 ou 2 pode ser impresso primeiro.

Este exemplo mostra a ideia-chave por trás do mecanismo. O trabalho é feito em corrotinas separadas, mas a emissão acontece apenas na corrotina que coleta o fluxo. Esta separação é a base da channelFlow. Ao mesmo tempo, este exemplo é intencionalmente minimalista. Ele não gerencia o fechamento do canal, cancelamento, buffer ou consumidores múltiplos. O construtor real lida com essas preocupações internamente. Na próxima seção refinaremos o exemplo para trazer mais próximo ao comportamento da channelFlow e preparar a base para entender a callbackFlow.

Fonte original

Conteúdo traduzido e adaptado pela redação do Notícias Mobile. Confira também a matéria na fonte original.

Leia a matéria completa