Вы можете использовать функцию async
builder для параллельной обработки загрузки данных:
class Presenter {
private var job: Job = Job()
private var scope = CoroutineScope(Dispatchers.Main + job) // creating the scope to run the coroutine. It consists of Dispatchers.Main (coroutine will run in the Main context) and job to handle the cancellation of the coroutine.
fun runInParallel() {
scope.launch { // launch a coroutine
// runs in parallel
val deferredList = listOf(
scope.asyncIO { processPages(urls, collection) },
scope.asyncIO { processPages(urls, collection2) },
scope.asyncIO { processPages(urls, collection3) }
)
deferredList.awaitAll() // wait for all data to be processed without blocking the UI thread
// do some stuff after data has been processed, for example update UI
}
}
private fun processPages(...) {...}
fun cancel() {
job.cancel() // invoke it to cancel the job when you don't need it to execute. For example when UI changed and you don't need to process data
}
}
Функция расширения asyncIO
:
fun <T> CoroutineScope.asyncIO(ioFun: () -> T) = async(Dispatchers.IO) { ioFun() } // CoroutineDispatcher - runs and schedules coroutines
GlobalScope.launch
не рекомендуется использовать , если вы не хотите, чтобы сопрограмма работала на протяжении всего времени жизни приложения и не была отменена преждевременно.
Редактировать: как упоминал Роман Елизаров, вы можете попытаться не использовать функцию awaitAll()
, если толькоВы хотите обновить пользовательский интерфейс или сделать что-то еще сразу после обработки всех данных.