Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

657
Visualizações
¿Cómo llamar a Kotlin coroutine en devoluciones de llamada de funciones componibles?

Quiero llamar a una función de suspensión dentro de una devolución de llamada de función componible.

 suspend fun getLocation(): Location? { /* ... */ } @Composable fun F() { val (location, setLocation) = remember { mutableStateOf<Location?>(null) } val getLocationOnClick: () -> Unit = { /* setLocation __MAGIC__ getLocation */ } Button(onClick = getLocationOnClick) { Text("detectLocation") } }

Si hubiera usado Rx, entonces podría simplemente subscribe .

Podría invokeOnCompletion y luego getCompleted , pero esa API es experimental.

No puedo usar launchInComposition en getLocationOnClick porque launchInComposition es @Composable y getLocationOnClick no puede ser @Composable .

¿Cuál sería la mejor manera de obtener el resultado de una función de suspensión dentro de una función normal, dentro de la función @Composable ?

over 4 years ago · Hanz Gallego
3 Respostas
Responde à pergunta

0

Esto funciona para mí:

 @Composable fun TheComposable() { val coroutineScope = rememberCoroutineScope() val (loadResult, setLoadResult) = remember { mutableStateOf<String?>(null) } IconButton( onClick = { someState.startProgress("Draft Loading...") coroutineScope.launch { withContext(Dispatchers.IO) { try { loadResult = DataAPI.getData() // <-- non-suspend blocking method } catch (e: Exception) { // handle exception } finally { someState.endProgress() } } } } ) { Icon(Icons.TwoTone.Call, contentDescription = "Load") }

También probé la siguiente función de ayuda, para forzar a los colegas desarrolladores a manejar Excepciones y finalmente limpiar el estado (también para hacer el mismo código (¡quizás!?) un poco más corto y (¡quizás!?) un poco más legible):

 fun launchHelper(coroutineScope: CoroutineScope, catchBlock: (Exception) -> Unit, finallyBlock: () -> Unit, context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job { return coroutineScope.launch(context, start) { withContext(Dispatchers.IO) { try { block() } catch (e: Exception) { catchBlock(e) } finally { finallyBlock() } } } }

y he aquí cómo usar ese método auxiliar:

 @Composable fun TheComposable() { val coroutineScope = rememberCoroutineScope() val (loadResult, setLoadResult) = remember { mutableStateOf<String?>(null) } IconButton( onClick = { someState.startProgress("Draft Loading...") launchHelper(coroutineScope, catchBlock = { e -> myExceptionHandling(e) }, finallyBlock = { someState.endProgress() } ) { loadResult = DataAPI.getData() // <-- non-suspend blocking method } } ) { Icon(Icons.TwoTone.Call, contentDescription = "Load") } }
over 4 years ago · Hanz Gallego Relatório

0

Puede usar viewModelScope de un ViewModel o cualquier otro ámbito de rutina.

Ejemplo de acción de eliminación para un elemento de LazyColumnFor que requiere una llamada de suspensión manejada por un modelo de vista.

 class ItemsViewModel : ViewModel() { private val _itemList = MutableLiveData<List<Any>>() val itemList: LiveData<List<Any>> get() = _itemList fun deleteItem(item: Any) { viewModelScope.launch(Dispatchers.IO) { TODO("Fill Coroutine Scope with your suspend call") } } } @Composable fun Example() { val itemsVM: ItemsViewModel = viewModel() val list: State<List<Any>?> = itemsVM.itemList.observeAsState() list.value.let { it: List<Any>? -> if (it != null) { LazyColumnFor(items = it) { item: Any -> ListItem( item = item, onDeleteSelf = { itemsVM.deleteItem(item) } ) } } // else EmptyDialog() } } @Composable private fun ListItem(item: Any, onDeleteSelf: () -> Unit) { Row { Text(item.toString()) IconButton( onClick = onDeleteSelf, icon = { Icons.Filled.Delete } ) } }
over 4 years ago · Hanz Gallego Relatório

0

Cree un alcance de rutinas, vinculado al ciclo de vida de su componible, y use ese alcance para llamar a su función de suspensión

 suspend fun getLocation(): Location? { /* ... */ } @Composable fun F() { // Returns a scope that's cancelled when F is removed from composition val coroutineScope = rememberCoroutineScope() val (location, setLocation) = remember { mutableStateOf<Location?>(null) } val getLocationOnClick: () -> Unit = { coroutineScope.launch { val location = getLocation() } } Button(onClick = getLocationOnClick) { Text("detectLocation") } }
over 4 years ago · Hanz Gallego Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda