¿Cómo puedo refactorizar este método de Kotlin con coroutines para que se ejecuten correctamente?
Toma este método
override suspend fun login(email: String, password: String): BaseResult<unit> {
coroutineScope {
try {
fetchMobileConfig()
} catch (e: Exception) {
// Sin manejar porque parece ser un proceso independiente.
}
}
val loginRequest = LoginRequest(
email = email,
password = password
)
return when (val response = loginNetwork.login(loginRequest)) {
is NetworkResponse.Success -> {
coroutineScope {
launch {
getUserData()
}
}
callSomeFinishingFunctionThatIsSuspending()
BaseResult.Ok(Unit)
}
is NetworkResponse.Error.Unauthorised -> {
BaseResult.Error(response.exception)
}
}
}
Me encontré con este método y quería refactorizarlo. Tengo algunas ideas, pero quiero ver si hay algo mejor que no haya considerado. En realidad, parece que funciona, pero se siente un poco caótico.
El método se llama desde un ViewModel con viewModelScope{}
.
Las funciones fetchMobileConfig()
y getUserData()
son un poco extrañas, pero actualmente parecen ser métodos independientes. Básicamente, si fallan, el inicio de sesión no debería fallar.
El BaseResult
devuelto se utiliza para informar al ViewModel del estado. Si te preguntas cómo se llama al método de inicio de sesión en loginNetwork
, se ve así:
override suspend fun login(loginRequest: LoginRequest): NetworkResponse<sessiontoken> {
return performRequest {
loginService.login(loginRequest)
}
}
Estoy satisfecho con el funcionamiento actual.
¿Cuál sería una forma mejor de escribir esta función a nivel de repositorio? Estoy abierto a otra estructura completamente diferente para ello.
davy.ai
Después de revisar el código proporcionado, aquí están algunas sugerencias para refactorizar:
fetchMobileConfig()
, se ignore de forma silenciosa. Al envolver la llamada a la función dentro de un bloque try-catch, puedes manejar la excepción de manera más elegante.Utiliza la concurrencia estructurada en lugar de lanzar nuevas corrutinas dentro de la función
login
. Al utilizarviewModelScope.launch
en tu ViewModel y llamar a la funciónlogin
desde ahí, puedes asegurarte de que todas las corrutinas se cancelen cuando se destruya el ViewModel.Considera pasar las dependencias como parámetros en lugar de depender del estado global. La función
login
actualmente está llamando a funciones que están definidas fuera de su ámbito (fetchMobileConfig()
ygetUserData()
). Al pasar estas funciones como parámetros, puedes hacer que las dependencias sean más explícitas y más fáciles de administrar.Aquí tienes un ejemplo de código refactorizado utilizando las sugerencias anteriores:
Al hacer que las funciones
fetchMobileConfig()
ygetUserData()
sean parámetros explícitos, las dependencias son más claras. Ahora se utiliza el bloquewithContext(Dispatchers.IO)
para llamar agetUserData()
en lugar de lanzar una nueva corrutina. Esto garantiza quegetUserData()
se ejecute en el hilo de entrada/salida (IO), lo cual es preferible para las operaciones en red.