Coroutines and RxJava3
我有以下方法,首先调用suspend方法,然后在相同的启动范围内调用RxJava。
我想知道是否有一种方法可以将Rxjava代码从viewModelScope.launch作用域中移除并返回fetchRecentUseCase.execute()的结果。
基本上,viewModelScope.launch是否有可能返回listOfProducts,而不是在启动范围内执行所有操作?
fun loadRecentlyViewed() {
viewModelScope.launch {
val listOfProducts = withContext(Dispatchers.IO) {
fetchRecentUseCase.execute()
}
val listOfSkus = listOfProducts.map { it.sku }
if (listOfSkus.isNotEmpty()) {
loadProductUseCase.execute(listOfSkus)
.subscribeOn(schedulersFacade.io)
.flatMap(convertProductDisplayUseCase::execute)
.map { /* work being done */ }
.observeOn(schedulersFacade.ui)
.subscribeBy(
onError = Timber::e,
onSuccess = { }
)
}
}
}suspend方法的用法
class FetchRecentUseCaseImp() {
override suspend fun execute(): List<Products> {
// Call to network
}
}非常感谢你提前
发布于 2021-08-03 20:35:54
对于协程,返回异步产生的单个项的方法是使用suspend函数。因此,您可以将函数标记为suspend,并将阻塞或异步回调函数转换为非阻塞代码,而不是启动协程。
启动协程的地方通常是UI交互(单击侦听器),或者是第一次创建类的时候(在Android上,这是在ViewModel构造函数或片段的onViewCreated()中)。
顺便说一句,任何suspend函数都期望调用者必须指定一个分派器,这是违反约定的。如果需要,它应该在内部委托,例如:
class FetchRecentUseCaseImp() {
override suspend fun execute(): List<Products> = withContext(Dispatchers.IO) {
// Synchronous call to network
}
}但是如果你正在使用一个像Retrofit这样的库,你只需要发出你的请求并暂停它,而不需要指定一个分派器,因为await()本身就是一个await()函数。
因此,您的函数应该如下所示:
suspend fun loadRecentlyViewed(): List<SomeProductType> {
val listOfSkus = fetchRecentUseCase.execute().map(Product::sku)
if (listOfSkus.isEmpty()) {
return emptyList()
}
return runCatching {
loadProductUseCase.execute(listOfSkus) // A Single, I'm assuming
.await() // Only if you're not completely stripping Rx from project
.map { convertProductDisplayUseCase.execute(it).await() } // Ditto for await()
.toList()
.flatten()
}.onFailure(Timber::e)
.getOrDefault(emptyList())
}https://stackoverflow.com/questions/68633074
复制相似问题