Open miroslavign opened 6 years ago
I'd assume all you need to do is make sure the Usecase function is suspend
so that you can call it from any coroutine. Considering that ViewModel
is typically the one who owns said CoroutineScope.
Let me try it like this,
I'm ok with ViewMmodel
being the owner, the question is should it be like:
abstract class UseCase<out Type, in Params> where Type : Any {
abstract suspend fun run(params: Params): Either<Failure, Type>
operator fun invoke(params: Params, coroutineDispatcher: CoroutineDispatcher, job: Job,
onResult: (Either<Failure, Type>) -> Unit = {}) {
val scope = CoroutineScope(coroutineDispatcher + job)
scope.launch {
onResult(run(params))
}
}
class None
}
and from viewModel
send/provide::
private val job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
getBooks.invoke(GetBooks.Params("e-book-fiction"), Dispatchers.IO, job) { it.either(::handleError, ::handleBooks) }
@miroslavign I refactored the UseCase
class like this:
abstract class UseCase<out Type, in Params> where Type : Any {
abstract suspend fun run(params: Params): Result<Type>
operator fun invoke(params: Params, job: Job, onResult: (Result<Type>) -> Unit = {}) {
val backgroundJob = CoroutineScope(job + Dispatchers.IO).async { run(params) }
CoroutineScope(job + Dispatchers.Main).launch { onResult(backgroundJob.await()) }
}
class None
}
I decided not to pass a CoroutineDispatcher
as a method parameter. You can easily set a CoroutineScope
based on a Job
object, for example job + Dispatchers.Main
. I'm not sure (I've not tested it yet) if this implementation would cancel the background task based on coroutine scope, but i cancel a job manually anyway inside OnCleared
method of my base ViewModel
in this way:
override fun onCleared() { job.cancel() super.onCleared() }
I also replaced Either
with Result
class (simpler implementation), but this solution should works for both cases.
Or in general, what modifications should be implemented to support new CoroutineContext in UseCase and from calling side ?