Na kotlinx.coroutines
biblioteca, você pode iniciar uma nova rotina usando launch
(com join
) ou async
(com await
). Qual a diferença entre eles?
fonte
Na kotlinx.coroutines
biblioteca, você pode iniciar uma nova rotina usando launch
(com join
) ou async
(com await
). Qual a diferença entre eles?
launch
é usado para disparar e esquecer a rotina . É como iniciar um novo tópico. Se o código dentro do launch
finalizar com exceção, ele será tratado como exceção não capturada em um encadeamento - geralmente impresso para stderr nos aplicativos JVM de back-end e trava os aplicativos Android. join
é usado para aguardar a conclusão da corotina lançada e não propaga sua exceção. No entanto, uma rotina infantil rotineira travada também cancela seu pai com a exceção correspondente.
async
é usado para iniciar uma rotina que calcula algum resultado . O resultado é representado por uma instância de Deferred
e você deve usá await
-lo. Uma exceção não capturada dentro do async
código é armazenada dentro do resultado Deferred
e não é entregue em nenhum outro lugar; ela será eliminada silenciosamente, a menos que seja processada. Você NÃO DEVE esquecer a corotina que você iniciou com a assíncrona .
Acho que este guia https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md é útil. Vou citar as partes essenciais
🦄 corotina
Assim, você pode pensar na corotina como algo que gerencia o encadeamento de maneira muito eficiente.
🐤 lançamento
Então
launch
inicia um thread em segundo plano, faz alguma coisa e retorna um token imediatamente comoJob
. Você pode chamarjoin
issoJob
para bloquear até que estelaunch
segmento seja concluído🦆 assíncrono
Então
async
inicia um thread em segundo plano, faz alguma coisa e retorna um token imediatamente comoDeferred
.Então
Deferred
é realmente umJob
. Consulte https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html🦋 assíncrono está ansioso por padrão
fonte
launch
easync
são usados para iniciar novas corotinas. Mas, eles os executam de maneira diferente.Eu gostaria de mostrar um exemplo muito básico que o ajudará a entender a diferença com muita facilidade
Neste exemplo, meu código está baixando 3 dados ao clicar no
btnCount
botão e mostrando apgBar
barra de progresso até que todo o download seja concluído. Existem 3suspend
funçõesdownloadTask1()
,downloadTask2()
edownloadTask3()
que faz download de dados. Para simular, useidelay()
essas funções. Essas funções aguardam e5 seconds
, respectivamente.8 seconds
5 seconds
Como usamos
launch
para iniciar essas funções de suspensão, aslaunch
executamos sequencialmente (uma a uma) . Isso significa que,downloadTask2()
iniciaria após adownloadTask1()
conclusão edownloadTask3()
só seria iniciado após adownloadTask2()
conclusão.Como na captura de tela de saída
Toast
, o tempo total de execução para concluir todos os 3 downloads levaria a 5 segundos + 8 segundos + 5 segundos = 18 segundos comlaunch
Como vimos, isso
launch
faz a execuçãosequentially
de todas as 3 tarefas. O tempo para concluir todas as tarefas era18 seconds
.Se essas tarefas forem independentes e se não precisarem do resultado da computação de outras tarefas, podemos executá-las
concurrently
. Eles começariam ao mesmo tempo e executariam simultaneamente em segundo plano. Isso pode ser feito comasync
.async
retorna uma instância doDeffered<T>
tipo, ondeT
são os tipos de dados que nossa função de suspensão retorna. Por exemplo,downloadTask1()
retornariaDeferred<String>
como String é o tipo de função de retornodownloadTask2()
retornariaDeferred<Int>
como Int é o tipo de função de retornodownloadTask3()
retornariaDeferred<Float>
como Float é o tipo de função de retornoPodemos usar o objeto de retorno de
async
do tipoDeferred<T>
para obter o valor retornado noT
tipo. Isso pode ser feito com aawait()
chamada. Verifique o código abaixo, por exemploDessa forma, lançamos as três tarefas simultaneamente. Portanto, meu tempo total de execução seria apenas o
8 seconds
tempo necessáriodownloadTask2()
, pois é o maior de todas as 3 tarefas. Você pode ver isso na seguinte captura de tela emToast message
fonte
launch
é paraasync
launch
easync
iniciarão novas corotinas. Você está comparando uma única corotina sem filhos com uma única corotina com três filhos. Você pode substituir cada uma dasasync
invocaçõeslaunch
e absolutamente nada mudaria em relação à simultaneidade.os dois construtores de corotina, nomeadamente launch e async, são basicamente lambdas com um receptor do tipo CoroutineScope, o que significa que seu bloco interno é compilado como uma função de suspensão, portanto, ambos são executados em modo assíncrono E ambos executam seu bloco sequencialmente.
A diferença entre o lançamento e o assíncrono é que eles permitem duas possibilidades diferentes. O construtor de lançamento retorna um trabalho, no entanto, a função assíncrona retornará um objeto adiado. Você pode usar o launch para executar um bloco que não espera nenhum valor retornado, por exemplo, gravar em um banco de dados ou salvar um arquivo ou processar algo basicamente chamado apenas de seu efeito colateral. Por outro lado, a assíncrona que retorna um adiado como afirmei anteriormente retorna um valor útil da execução de seu bloco, um objeto que agrupa seus dados, para que você possa usá-lo principalmente como resultado, mas possivelmente também como efeito colateral. Nota: você pode retirar o diferido e obter seu valor usando a função aguardar, que bloqueará a execução de suas instruções até que um valor seja retornado ou exceções sejam lançadas!
o construtor de corotina (inicialização e async) é cancelável.
mais alguma coisa ?: sim com o lançamento, se uma exceção for lançada dentro de seu bloco, a corotina é automaticamente cancelada e as exceções são entregues. Por outro lado, se isso acontecer com a assíncrona, a exceção não será propagada mais e deverá ser capturada / manipulada dentro do objeto Adiado retornado.
mais sobre coroutines https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html https://www.codementor.io/blog/kotlin-coroutines-6n53p8cbn1
fonte
lançamento retorna um trabalho
async retorna um resultado (trabalho adiado)
O lançamento com junção é usado para aguardar a conclusão do trabalho. ele simplesmente suspende a corotina chamando join (), deixando o encadeamento atual livre para realizar outro trabalho (como executar outra corotina) enquanto isso.
assíncrono é usado para calcular alguns resultados. Ele cria uma rotina e retorna seu resultado futuro como uma implementação do Adiado. A corrotina em execução é cancelada quando o diferido resultante é cancelado.
Considere um método assíncrono que retorna um valor de sequência. Se o método assíncrono for usado sem aguardar, ele retornará uma sequência adiada, mas se for aguardado, você obterá uma sequência como resultado
A principal diferença entre assíncrono e inicialização. Adiado retorna um valor específico do tipo T depois que a Coroutine termina a execução, enquanto Job não.
fonte
Async vs Launch Async vs Launch Diff Image
iniciar / assíncrono sem resultado
assíncrono para resultado
fonte