Я относительно новичок в сопрограммах, поэтому мне было интересно, как я могу решить свою небольшую локальную проблему без значительной перестройки моих Android кодов.
Вот простая настройка. Моя ViewModel вызывает функцию suspend
из репозитория:
// ...ViewModel.kt
fun loadData() {
viewModelScope.launch {
val data = dataRepository.loadData()
}
}
Это очень удобно, поскольку у меня есть viewModelScope
, подготовленный для меня с помощью Android, и я вызываю функцию приостановки из своего репозитория. Мне все равно, как хранилище загружает данные, я просто приостанавливаю, пока они не будут возвращены мне.
Мой хранилище данных выполняет несколько вызовов, используя Retrofit
:
//...DataRepository.kt
@MainThread
suspend fun loadData(): ... {
// Retrofit switches the contexts for me, just
// calling `suspend fun getItems()` here.
val items = retrofitApi.getItems()
val itemIDs = items.map { it.id }
// Next, getting overall list of subItems for each item. Again, each call and context
// switch for `suspend fun retrofitApi.getSubItems(itemID)` is handled by Retrofit.
val subItems = itemIDs.fold(mutableListOf()) { result, itemID ->
result.apply {
addAll(retrofitApi.getSubItems(itemID)) // <- sequential :(
}
}
return Pair(items, subItems)
}
Как вы Можно видеть, поскольку loadData()
является функцией приостановки, все вызовы retrofitApi.getSubItem(itemID)
будут выполняться последовательно.
Однако я хотел бы выполнить их параллельно, что-то вроде async() / await()
в сопрограммах будет делать .
Я хочу оставить коды ViewModel
нетронутыми - не важно, как загружаются данные, просто запускает функцию приостановки из собственной области видимости. Я также не хочу передавать какие-либо области видимости или другие объекты в мой репозиторий.
Как я могу сделать это внутри функции приостановки? Присутствие там как-то неявно присутствует? Возможно ли / разрешено / положительно ли использовать async()
? 1025 *