首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混合搭配协程和Rxjava

混合搭配协程和Rxjava
EN

Stack Overflow用户
提问于 2021-08-03 08:55:23
回答 1查看 534关注 0票数 0

Coroutines and RxJava3

我有以下方法,首先调用suspend方法,然后在相同的启动范围内调用RxJava。

我想知道是否有一种方法可以将Rxjava代码从viewModelScope.launch作用域中移除并返回fetchRecentUseCase.execute()的结果。

基本上,viewModelScope.launch是否有可能返回listOfProducts,而不是在启动范围内执行所有操作?

代码语言:javascript
复制
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方法的用法

代码语言:javascript
复制
class FetchRecentUseCaseImp() {
    override suspend fun execute(): List<Products> {
        // Call to network 
    }
}

非常感谢你提前

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-03 20:35:54

对于协程,返回异步产生的单个项的方法是使用suspend函数。因此,您可以将函数标记为suspend,并将阻塞或异步回调函数转换为非阻塞代码,而不是启动协程。

启动协程的地方通常是UI交互(单击侦听器),或者是第一次创建类的时候(在Android上,这是在ViewModel构造函数或片段的onViewCreated()中)。

顺便说一句,任何suspend函数都期望调用者必须指定一个分派器,这是违反约定的。如果需要,它应该在内部委托,例如:

代码语言:javascript
复制
class FetchRecentUseCaseImp() {
    override suspend fun execute(): List<Products> = withContext(Dispatchers.IO) {
        // Synchronous call to network 
    }
}

但是如果你正在使用一个像Retrofit这样的库,你只需要发出你的请求并暂停它,而不需要指定一个分派器,因为await()本身就是一个await()函数。

因此,您的函数应该如下所示:

代码语言:javascript
复制
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())
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68633074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档