RxJava的副作用

RxJava的观察者类有许多方法,可以转换发出的字节流为任何你需要的数据类型。这些方法是RxJava非常核心的方法,是RxJava具有吸引力的重要缘故。

但是有些方法无论如何都不能改变流本身,我称这些方法为副作用(Side Effect)方法。

关于副作用方法,我的一点观点

副作用方法并不影响你的字节流本身。相反地,当某些事件发生时它们被调用,这样允许你去处理这些事件。

举个例子:当一些错误发生了,如果你想在你的订阅者回调函数之外做些处理,你可以使用 doOnError()方法并且将被使用的功能接口作为参数传递给方法,任何一个错误出现都可以这样做:

someObservable
  .doOnError(new Action1() {
     @Override
     public void call(Throwable t) {
        // use this callback to clean up resources,
        // log the event or or report the
        // problem to the user
     }
  })
  //…

call()方法是最重要的部分。在订阅者的onError()方法被执行前这个方法的代码将被执行。

除了异常外,RxJava提供了更多可处理的事件:

事件和事件相应的副作用操作

Method Functional Interface Event
doOnSubscribe() Action0 A subscriber subscribes to the Observable
doOnUnsubscribe() Action0 A subscriber unsubscribes from the subscription
doOnNext() Action1 The next item is emitted
doOnCompleted() Action0 The Observable will emit no more items
doOnError() Action1 An error occurred
doOnTerminate() Action0 Either an error occurred or the Observable will emit no more items
doOnEach() Action1< Notification< T>> Either an item was emitted, the Observable completes or an error occurred. The Notification object contains information about the type of event
doOnRequest() Action1 A downstream operator requests to emit more items


< T>要么指的是被传递进来的参数类型,要么指的是,像onError()方法这种情况里,异常可以抛出的类型

功能接口全是Action0 或者 Action1. 类型。这意味着这些接口的单一方法不返回任何值并且要么没有参数,要么只有一个参数,视特定的事件而定。

因为这些方法不返回任何值,他们不能被用来改变传递出来的数据,因此无论如何也不能改变字节流本身。相反这些方法将意图引起副作用方法,像在磁盘上写入一些东西、清空状态或者其他任何能操纵系统本身状态而不是事件流本身的事情。

注意:副作用方法本身(doOnNext(),doOnCompleted()等等)返回可观察事件,这保持了接口的流畅性。但是,这些副作用方法返回的可观察者和源观察者具有相同的类型,并且发射出同样的东西。

他们被用来在做什么?

既然他们不改变流本身,那必然有其他的用途。我在这里陈述三个例子,关于你使用这些方法可以达到的事情。

使用doOnNext()来调试

在flatMap()里使用doOnError()作为错误处理。

使用doOnNext()去保存/缓存网络结果

所以,让我们来具体看下如何使用这些例子。

使用 doOnNext()调试

使用RxJava,有时候你会疑惑为什么你的观察者不像预想中那样起作用。尤其是当你刚刚开始使用RxJava的时候。因为你用了一个流畅的API去转换一些源码为某些你想订阅的事件,你只看到了你在这个传输管道的末尾能得到的东西。

当我开始学习RxJava的时候,我有一些关于java流的使用经验。同样的,你在这里也有一些相同的问题。你有一个顺畅好用的API去转换一种类型的流为另一种类型的流。但是为什么它不像预期那样起作用呢?

在Java 8的流里,你有方法peek()可用。所以当我开始使用RxJava时,我好奇有哪些地方可以比较可以被利用。嗯,有的。其实,RxJava为我们提供了更多!

你可以在进程管道的任何地方使用doOnNext()方法,去查看发生了什么并且获得中间结果。

例子:

Observable someObservable = Observable
        .from(Arrays.asList(new Integer[]{2, 3, 5, 7, 11}))
        .doOnNext(System.out::println)
        .filter(prime -> prime % 2 == 0)
        .doOnNext(System.out::println)
        .count()
        .doOnNext(System.out::println)
        .map(number -> String.format(“Contains %d elements”, number));
Subscription subscription = o.subscribe(
        System.out::println,
        System.out::println,
        () -> System.out.println(“Completed!”));

这里是代码的输出:

2
3
3
5
5
7
7
11
11
4
Contains 4 elements
Completed!     

当你的观察者对象表现不如你所预期时,用这种方式你可以搜集到有价值的信息,关于观察者对象是如何运行的。

doOnError()和doOnCompleted()方法在调试你管道的状态时也是有用的。

注意:如果你使用RxJava开发安卓,请看一下Frodo和Fernando Ceja的文章,这些文章解释了使用Frodo的动机,使用Frodo可以让你通过注解的方式去调试你的观察者和订阅者。

给出了使用doOnNext()和doOnError()的方式,但并没有改变太多系统的状态——除了膨胀了你的日志和减缓了一切运行程序。

但这些操作有其他的用处,事实上,在这些用例里,你使用这些方法确实可以改变你系统的状态 ,来看一看他们吧。

在flatMap()里使用doOnError()

假设你使用Retrofit来访问网络资源。自从Retrofit支持观察者以来,在你的处理链里,你可以很容易的通过flatMap()使用这些调用。

哎,网络关联调用能引起很多方面的错误——尤其在手机上。在这个案例里,你也许不想让观察者停止工作,但如果你独自依赖于订阅者的回调方法onError(),它将停止工作。

但是请记住在方法flatMap()内有观察者。因此,你可以使用doOnError()方法通过某种方式更改UI,然而仍然有一个工作着的观察者流侦测未来可能发生的事情。

所以这个案例具体如下:

flatMap(id -> service.getPost()
   .doOnError(t -> {
      // report problem to UI
   })
   .onErrorResumeNext(Observable.empty())
)

如果查询你的远程资源作为经常会发生的UI事件的响应结果,这个方法尤其有用。

使用doOnNext()去保存/缓存网络结果

如果在业务链的中的某个点,你创建了一个网络调用,就可以使用doOnNext()去存储即将获得的结果到本地数据库或者将结果放入某些缓存里。

它就像接下来的这些代码行一样简单:

// getOrderById is getting a fresh order
// from the net and returns an observable of orders
// Observable<Order> getOrderById(long id) {…}
Observable.from(aListWithIds)
     .flatMap(id -> getOrderById(id)
                          .doOnNext(order -> cacheOrder(order))
     // carry on with more processing  

总结

如你所看见,你可以用多种方式使用RxJava的副作用方法。即使他们没有改变事件流本身,但是它们能改变你整个系统的状态。这可能会简单得像在进程管道中的某个确定的点记录下可观察者的当前的事件,再把它们作为网络回调的结果写入数据库中。

转自:http://codecloud.net/rxjavas-side-effect-methods-6628.html?utm_source=tuicool&utm_medium=referral

本文由程序员的资料库技术翻译小组–头目14同学翻译,有翻译不正确的地方,请帮忙更正,谢谢支持。

英文原文:RxJava’s Side Effect Methods

欢迎转载,转载请务必保留译文出处和原文出处,谢谢合作!

时间: 2024-10-31 08:38:09

RxJava的副作用的相关文章

RxJava 并发之数据流发射太快如何办

Backpressure Rx 中的数据流是从一个地方发射到另外一个地方.每个地方处理数据的速度是不一样的.如果生产者发射数据的速度比消费者处理的快会出现什么情况?在同步操作中,这不是个问题,例如: // Produce Observable<Integer> producer = Observable.create(o -> { o.onNext(1); o.onNext(2); o.onCompleted(); }); // Consume producer.subscribe(i

RxJava操作符doOnNext

doOnNext官方介绍: The doOnNext operator is much like doOnEach(Action1) except that the Action that you pass it as a parameter does not accept a Notification but instead simply accepts the emitted item. 可以这么理解: do系列的作用是side effect,当onNext发生时,它被调用,不改变数据流.

RxJava 和 RxAndroid 三(生命周期控制和内存优化)

RxJava 和 RxAndroid 三(生命周期控制和内存优化) rxjava rxandroid 前言:对Rxjava.Rxandroid不了解的同学可以先看看 RxJava 和 RxAndroid RxJava 和 RxAndroidRxJava 和 RxAndroid 二(操作符的使用) RxJava使我们很方便的使用链式编程,代码看起来既简洁又优雅.但是RxJava使用起来也是有副作用的,使用的越来越多的订阅,内存开销也会变得很大,稍不留神就会出现内存溢出的情况,这篇文章就是介绍Rxj

Rxjava的介绍与使用

最近RxJava越来越流行了,在移动端也越来越多的项目开始使用这个框架了!唯一的问题就是上手不容易,尤其是大部分人之前都是使用命令式编程语言.但是一旦你弄明白了,你就会发现RxJava真是太棒了. 这里仅仅是帮助你了解RxJava,整个系列共有四篇文章,希望你看完这四篇文章之后能够了解RxJava背后的思想,并且喜欢上RxJava. 基础 RxJava最核心的两个东西是Observables(被观察者,事件源)和Subscribers(观察者).Observables发出一系列事件,Subscr

认识一下Rxjava

Rxjava 一.为啥要用它?她能干啥? 网络请求等耗时操作必须放到子线程.线程切换 reactive 式编程.代码更加健壮 使用观察者模式 创建:Rx可以方便的创建事件流和数据流 组合:Rx使用查询式的操作符组合和变换数据流 监听:Rx可以订阅任何可观察的数据流并执行操作 简化代码 函数式风格:对可观察数据流使用无副作用的输入输出函数,避免了程序里错综复杂的状态 简化代码:Rx的操作符通通常可以将复杂的难题简化为很少的几行代码 异步错误处理:传统的try/catch没办法处理异步计算,Rx提供

我把RXjava的源码和这份面试都给你了,你还告诉我面不过拿不到offer?(一)

就在前不久做了一个关于RXJava的相关教学视频,过后整理了关于RxJava的预习资料和相关内容以及图文和相关源码,需要借鉴的可以和我联系~ 一丶 面试辅助路线(全部内容在完整的PDF里都有讲解) (顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)https://github.com/xiangjiana/Android-MS(VX:mm14525201314) 二丶 RXJava预习: JAVA设计模式之观察者模式 1.初步认识 观察者模式的定义:在对象之间定义了一对多的依赖,

一起来造一个RxJava,揭秘RxJava的实现原理

RxJava是一个神奇的框架,用法很简单,但内部实现有点复杂,代码逻辑有点绕.我读源码时,确实有点似懂非懂的感觉.网上关于RxJava源码分析的文章,源码贴了一大堆,代码逻辑绕来绕去的,让人看得云里雾里的.既然用拆轮子的方式来分析源码比较难啃,不如换种方式,以造轮子的方式,将源码中与性能.兼容性.扩展性有关的代码剔除,留下核心代码带大家揭秘RxJava的实现原理. 什么是响应式编程 首先,我们需要明确,RxJava是Reactive Programming在Java中的一种实现.什么是响应式编程

RxJava概叙

给Android开发者的 RxJava 详解:http://gank.io/post/560e15be2dca930e00da1083 响应式编程是一种异步数据流交互的编程范式,而RxJava就是基于事件操作异步数据流在Java上实现的库 核心的理念是将一切都当做数据流来看待,各种变量,用户输入,数据结构,缓存等等 而Rx库提供了高度抽象的函数来操作流,创建.流入流出.过滤.合并.映射等等各种变换 不仅如此,Rx库还使得异步操作,和错误处理变得非常简洁. 使用了RxJava后明显的好处就是 1解

RxJava从入门到放弃---关于RxJava-入门必看

RxJava 到底是什么 RxJava 好在哪 API 介绍和原理简析 1. 概念:扩展的观察者模式 观察者模式 RxJava 的观察者模式 2. 基本实现 1) 创建 Observer 2) 创建 Observable 3) Subscribe (订阅) 4) 场景示例 a. 打印字符串数组 b. 由 id 取得图片并显示 3. 线程控制 -- Scheduler (一) 1) Scheduler 的 API (一) 2) Scheduler 的原理 (一) 4. 变换 1) API 2) 变