Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
RxJava2-合并流中的值和副作用_Java_Android_Kotlin_Rx Java2 - Fatal编程技术网

RxJava2-合并流中的值和副作用

RxJava2-合并流中的值和副作用,java,android,kotlin,rx-java2,Java,Android,Kotlin,Rx Java2,我试图将一些基于RxJava2的通用逻辑提取到可重用组件中。让我们假设我有以下代码: someSingle .doOnSuccess { // update UI based on side effect } .subscribeOn(...) .observeOn(...) .subscribe( value -> // update UI based on value throwable -> // handle e

我试图将一些基于RxJava2的通用逻辑提取到可重用组件中。让我们假设我有以下代码:

someSingle
    .doOnSuccess { // update UI based on side effect }
    .subscribeOn(...)
    .observeOn(...)
    .subscribe(
        value -> // update UI based on value
        throwable -> // handle error
    )
我想将其包装成一个可重用组件,公开一个返回可流动事件的方法。客户端将接收事件并相应地更新UI。我的目标是不在可重用组件中引用视图。我希望方法是这样的:

fun reusableMethod(...) : Flowable<Event> { ... }
我还考虑了一些备选方案:

  • 使用传递给
    someReusableMethod()
    的回调通知客户端
    SideEffectEvent
    s-看起来非常不自然,使用回调和要订阅的流不是一种好的代码样式
  • 使用单个
    PublishProcessor
    。将副作用发布到它并使用它订阅原始的
    单曲
    。在可重用组件中公开一个
    cleanUp()
    方法,以便客户端在决定处理流时可以处理该流

我期待您的建议和想法。

首先,它不必是可流动的。它可以是一个简单的
可观察的
。但以下解决方案在这两种情况下都应该有效。在这里阅读更多

这段代码没有经过测试,我写这段代码是为了让您对如何实现这一点有一个简单的想法

// a sealed class representing current state 
sealed class ViewState {
    object Loading : ViewState() // using object because we do not need any data in cass of loading
    data class Success(val data: List<Model>) : ViewState()
    data class Error(val t: Throwable) : ViewState()
}

// an observalbe or flowable returning a single object ViewState
// it will always return ViewState class containing either data or error or loading state
return service.getData()
    .map { data -> ViewState.Success(data) } // on successful data fetch
    .startWith(ViewState.Loading()) // show loading on start of fetch
    .onErrorReturn { exception -> ViewState.Error(exception) } // return error state 
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())

// somewhere in Activity or in multiple activities subscribe to above observable
subscribe({ viewState ->
     when {
         viewState.Loading -> showProgressView()
         viewState.Error -> showErrorView(viewState.t)
         viewState.Success -> showData(viewState.data)
         else -> IllegalArgumentException("Invalid Response")
     }

})
//表示当前状态的密封类
密封类视图状态{
对象加载:ViewState()//正在使用对象,因为加载的cass中不需要任何数据
数据类成功(val数据:列表):ViewState()
数据类错误(val t:Throwable):ViewState()
}
//返回单个对象视图状态的可观察或可流动视图
//它将始终返回包含数据、错误或加载状态的ViewState类
return服务
.map{data->ViewState.Success(data)}//在成功获取数据时
.startWith(ViewState.load())//在开始提取时显示加载
.OneErrorReturn{exception->ViewState.Error(exception)}//返回错误状态
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//在活动中的某处或在多个活动中订阅上述可观察到的
订阅({viewState->
什么时候{
正在加载->showProgressView()
viewState.Error->showErrorView(viewState.t)
viewState.Success->showData(viewState.data)
else->IllegalArgumentException(“无效响应”)
}
})
这个怎么样:

之前:

someSingle
    .operation1()
    .operation2()
    .doOnSuccess { // update UI based on side effect }
    .operation3()
    .operation4()
    .subscribeOn(...)
    .observeOn(...)
    .subscribe(
        value -> // update UI based on value
        throwable -> // handle error
    )
可重复使用:

fun reusableMethod(...): Flowable<Event> = 
    someSingle
        .operation1()
        .operation2()
        .flatMapPublisher {
            Single.concat(
                Single.just(getSideEffectEvent(it)),
                Single.just(it)
                    .operation3()
                    .operation4()
                    .map { value -> getValueEvent(value) }
            )
        }
        .subscribeOn(...)
        .observeOn(...)
fun可重用方法(…):可流动=
某个人
.操作1()
.操作2()
.flatMapPublisher{
单瓣海螺(
Single.just(getSideEffectEvent(it)),
单身,就是(它)
.操作3()
.操作4()
.map{value->getValueEvent(value)}
)
}
.subscribeOn(…)
.观察(…)

您可以使用
Flowable#startWith
,进一步简化此过程,并避免
Single#concat()

它必须是可流动的吗?也许您可以将单个事件发布到一个可变LiveData对象,并在ViewModel中观察到这一点。@Vesper Yope,它必须是一个可流动的,它必须是一个可流动的,才能适合应用程序体系结构。您的示例工作得非常完美,但我有多个流与
flatMap()
链接,我还需要将以前的流中的事件传播到订阅者。现在,这种情况太广泛,我无法提供答案。如果你能根据自己的情况更新问题,并为问题提供一个清晰的背景,那么也许我或其他人能够提供帮助。
fun reusableMethod(...): Flowable<Event> = 
    someSingle
        .operation1()
        .operation2()
        .flatMapPublisher {
            Single.concat(
                Single.just(getSideEffectEvent(it)),
                Single.just(it)
                    .operation3()
                    .operation4()
                    .map { value -> getValueEvent(value) }
            )
        }
        .subscribeOn(...)
        .observeOn(...)