【发布时间】:2020-04-23 20:51:42
【问题描述】:
考虑这个用例:
class GetPhotosUseCase(
private val photosRepository: IPhotosRepository,
private val favoritesRepository: IFavoritesRepository
) : IGetPhotosUseCase {
override suspend fun getPhotos(): List<Photo> {
val photos = photosRepository.getPhotos()
val favoriteIds = favoritesRepository.getFavoriteIds()
return photos.map {
it.copy(isFavorite = favoriteIds.contains(it.id))
}
}
}
interface IPhotosRepository {
suspend fun getPhotos(): List<Photo>
}
interface IFavoritesRepository {
suspend fun getFavoriteIds(): List<Int>
}
我从 2 个不同的来源获取数据并将它们组合起来。现在,这是连续运行的。
当我想并行运行photosRepository.getPhotos() 和favoritesRepository.getFavoriteIds() 以节省执行时间时,我的幼稚做法是:
override suspend fun getPhotos(): List<Photo> {
val photosDeferred = GlobalScope.async { photosRepository.getPhotos() }
val favoriteIdsDeferred = GlobalScope.async { favoritesRepository.getFavoriteIds() }
return applyFavoritesToPhotos(photosDeferred.await(), favoriteIdsDeferred.await())
}
private fun applyFavoritesToPhotos(photos: List<Photo>, favoriteIds: List<Int>) = photos.map {
it.copy(isFavorite = favoriteIds.contains(it.id))
}
不鼓励使用GlobalScope,因为调用者的生命周期结束时不会取消作业。
由于我的用例不知道调用者的生命周期,它应该使用哪个范围? 将范围传递给用例是否是一个令人满意的解决方案,例如:
override suspend fun getPhotos(scope: CoroutineScope): List<Photo> {
val photosDeferred = scope.async { photosRepository.getPhotos() }
val favoriteIdsDeferred = scope.async { favoritesRepository.getFavoriteIds() }
return applyFavoritesToPhotos(photosDeferred.await(), favoriteIdsDeferred.await())
}
或者这里的理想解决方案是什么?用例是否应该返回一个Deferred 并让调用者await 它?
【问题讨论】:
标签: android kotlin coroutine kotlin-coroutines