RxJava 2.0有什么不同(译)

为什么翻译这篇文章

ReactiveX 于2016.10.29 发布了正式版RxJava 2.0.0,但到我写本文章为止,还没有发现谁完整的翻译了官方的这篇文档 What’s-different-in-2.0

秉着旧事物迟早被新事物替代的想法,于是我用我没过6级的英语咬牙翻译下这篇文章,希望能帮助年轻的司机。但鉴于本人水平有限,翻译得不好,如果各位大神发现哪里写错了,欢迎发邮件通知我,我会在第一时间改正,本人邮箱:[email protected]

关于我们

作者: 宇不语
个人网站: www.ittianyu.com
个人博客: blog.csdn.net/qq_35064774
Github: github.com/ittianyu
本文地址:点这里

开始

RxJava 2.0 已经按照Reactive-Streams specification规范完全的重写了。2.0 已经独立于RxJava 1.x而存在。

因为Reactive-Streams有一个不同的构架,它改变了一些以往RxJava的用法。这份文档尝试去总结所发生的变化,并描述如何把1.x的代码改写成符合2.x规则的代码。

这个页面是为本库用户写的,这将会有一个分界页面,专门留给为RxJava库开发者以及那些希望为2.x版本开发自定义操作符的用户

Maven 地址和基础包

为了让 RxJava 1.x 和 RxJava 2.x 相互独立,我们把RxJava 2.x 被放在了maven io.reactivex.rxjava2:rxjava:2.x.y 下,类放在了 io.reactivex 包下

用户从 1.x 切换到 2.x 时需要导入的相应的包,但注意不要把1.x和2.x混淆了。

Javadoc

Java 文档

官方2.x的 Java 文档 http://reactivex.io/RxJava/2.x/javadoc/

Nulls

RxJava 2x 不再支持 null 值,如果传入一个null会抛出 NullPointerException

Observable.just(null);

Single.just(null);

Observable.fromCallable(() -> null)
    .subscribe(System.out::println, Throwable::printStackTrace);

Observable.just(1).map(v -> null)
    .subscribe(System.out::println, Throwable::printStackTrace);

这意味着 Observable<Void> 不再发射任何值,而只是正常结束或者抛出异常。API 设计者可以定义 Observable<Object> 这样的观察者, 因为并不确定具体是什么类型的 Object。例如,如果你需要一个 signaller-like ,你可以定义一个共享的枚举类型,它是一个单独的实例onNext‘d:

enum Irrelevant { INSTANCE; }

Observable<Object> source = Observable.create((ObservableEmitter<Object> emitter) -> {
   System.out.println("Side-effect 1");
   emitter.onNext(Irrelevant.INSTANCE);

   System.out.println("Side-effect 2");
   emitter.onNext(Irrelevant.INSTANCE);

   System.out.println("Side-effect 3");
   emitter.onNext(Irrelevant.INSTANCE);
});

source.subscribe(e -> { /* Ignored. */ }, Throwable::printStackTrace);

Observable 和 Flowable

在RxJava 0.x中关于介绍backpressure部分有一个小小的遗憾,那就是没有用一个单独的类,而是使用了Observable。 主要的背压问题是有很多很火的代码,像UI events,不能合理的背压,导致了无法意料的 MissingBackpressureException

我们试图在 2.x 中纠正这个问题。因此我们把io.reactivex.Observable 设计成非背压的,并增加一个新的io.reactivex.Flowable 去支持背压。

好消息是操作符的名字几乎没有改动。坏消息是当你执行’organize imports’时必须要格外的小心,它可能无意的给你选择一个非背压的io.reactivex.Observable

Single

2.x 的Single类可以发射一个单独onSuccessonError消息。它现在按照Reactive-Streams规范被重新设计,SingleObserver改成了如下的接口。

interface SingleObserver<T> {
    void onSubscribe(Disposable d);
    void onSuccess(T value);
    void onError(Throwable error);
}

并遵循协议 onSubscribe (onSuccess | onError)?.

Completable

Completable大部分和以前的一样。因为它在1.x的时候就是按照Reactive-Streams的规范进行设计的。

命名上有些变化,
rx.Completable.CompletableSubscriber 变成了 io.reactivex.CompletableObserveronSubscribe(Disposable):

interface CompletableObserver<T> {
    void onSubscribe(Disposable d);
    void onComplete();
    void onError(Throwable error);
}

并且仍然遵循协议 onSubscribe (onComplete | onError)?.

Maybe

RxJava 2.0.0-RC2 介绍了一个新的类型 Maybe 。从概念上来说,它是SingleCompletable 的结合体。它可以发射0个或1个通知或错误的信号。

Maybe类结合了MaybeSource, MaybeObserver<T>作为信号接收接口,同样遵循协议onSubscribe (onSuccess | onError | onComplete)?。因为最多有一个元素被发射,Maybe没有背压的概念。

这意味着调用onSubscribe(Disposable)请求可能还会触发其他 onXXX方法。和Flowable不同,如果那有一个单独的值要发射,那么只有onSuccess被调用,onComplete不被调用。

这个新的类,实际上和其他Flowable的子类操作符一样可以发射0个或1个序列。

Maybe.just(1)
.map(v -> v + 1)
.filter(v -> v == 1)
.defaultIfEmpty(2)
.test()
.assertResult(2);

Base reactive interfaces

基础reactive接口

按照Reactive-Streams风格的Flowable实现了 Publisher<T>接口,其他基础类也实现了类似的基础接口

interface ObservableSource<T> {
    void subscribe(Observer<? super T> observer);
}

interface SingleSource<T> {
    void subscribe(SingleObserver<? super T> observer);
}

interface CompletableSource {
    void subscribe(CompletableObserver observer);
}

interface MaybeSource<T> {
    void subscribe(MaybeObserver<? super T> observer);
}

因此,很多操作符需要从用户接收PublisherXSource的一些基础的类型。

Flowable<R> flatMap(Function<? super T, ? extends Publisher<? extends R>> mapper);

Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper);

通过Publisher作为输入,你可以组合其他的遵从Reactive-Streams规范的库,而不需要包裹或把它们转换成Flowable

如果一个操作符必须要提供一个基础类,那么用户将会收到一个完整的基础类。

Flowable<Flowable<Integer>> windows = source.window(5);

source.compose((Flowable<T> flowable) -> 
    flowable
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread()));

Subjects 和 Processors

在Reactive-Streams规范中,Subject类似于行为,即消费者和提供者的事件在同一时间发生。随着Observable/Flowable的分离,支持背压的类都是遵从Reactive-Streams规范的FlowableProcessor<T>的子类。一个关于Subject重要的变化是它们不再支持T -> R这样的转换。

在 2.x 中, io.reactivex.subjects.AsyncSubject, io.reactivex.subjects.BehaviorSubject, io.reactivex.subjects.PublishSubject, io.reactivex.subjects.ReplaySubjectio.reactivex.subjects.UnicastSubject 不支持背压。

io.reactivex.processors.AsyncProcessor, io.reactivex.processors.BehaviorProcessor, io.reactivex.processors.PublishProcessor, io.reactivex.processors.ReplayProcessorio.reactivex.processors.UnicastProcessor 支持背压。 BehaviorProcessorPublishProcessor 不能协同请求下级的订阅者,如果下游不能保存,则会发射一个MissingBackpressureException异常。其他XProcessor类支持对下游订阅者背压,但是当被订阅源时,它们会无限制的消费。

其他类

rx.observables.ConnectableObservable 现在是io.reactivex.observables.ConnectableObservable<T>io.reactivex.flowables.ConnectableFlowable<T>

GroupedObservable

rx.observables.GroupedObservable 现在是io.reactivex.observables.GroupedObservable<T>io.reactivex.flowables.GroupedFlowable<T>.

在1.x中,你可以用GroupedObservable.from()创建一个实例。在2.x中,所有实例都直接继承了GroupedObservable,因此这个工厂方法不再可用; 现在整个类都是抽象的。

不过你可以继承类然后添加你自定义的subscribeActual行为来达到1.x中相似的功能。

class MyGroup<K, V> extends GroupedObservable<K, V> {
    final K key;

    final Subject<V> subject;

    public MyGroup(K key) {
        this.key = key;
        this.subject = PublishSubject.create();
    }

    @Override
    public T getKey() {
        return key;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        subject.subscribe(observer);
    }
}

功能接口

1.x 和 2.x 是跑在Java 6以上的虚拟机的,所以我们不能使用Java8的功能接口(functional interfaces),比如java.util.function.Function。但我们可以按照这个例子来定义自己的功能接口(functional interfaces)。

一个值得注意的区别是所有的功能接口(functional interfaces)都定义了throws Exception。这对于consumers 和 mappers 来说是一个巨大的便利,你不需要用try-catch捕获异常。

Flowable.just("file.txt")
.map(name -> Files.readLines(name))
.subscribe(lines -> System.out.println(lines.size()), Throwable::printStackTrace);

如果文件不存在或者不可读,结尾的consumer会直接输出IOException。你可以直接调用Files.readLines(name)而不需要捕获异常。

Actions

为了减少组件数量,2.x中没有定义Action3-Action9ActionN

保留的action接口按照Java 8 functional风格命名。 无参数的Action0 被操作符io.reactivex.functions.ActionScheduler代替。Action1被重命名为ConsumerAction2 被重命名为BiConsumerActionNConsumer<Object[]> 代替。

Functions

我们按照Java 8的命名风格定义了io.reactivex.functions.Functionio.reactivex.functions.BiFunction, 把Func3 - Func9 分别改成了 Function3 - Function9FuncNFunction<Object[], R>代替。

此外,操作符不再使用Func1<T, Boolean>但原始返回类型为Predicate<T>

io.reactivex.functions.Functions类提供了常见的转换功能Function<Object[], R>

Subscriber

Reactive-Streams规范有自己的Subscriber。这个接口是轻量级的,并且把请求管理和取消机制整合进了一个单独的接口org.reactivestreams.Subscription,而不是分别用rx.Producerrx.Subscription。这就可以用比1.x中rx.Subscriber更少的内部状态来创建一个stream consumers。

Flowable.range(1, 10).subscribe(new Subscriber<Integer>() {
    @Override
    public void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE);
    }

    @Override
    public void onNext(Integer t) {
        System.out.println(t);
    }

    @Override
    public void onError(Throwable t) {
        t.printStackTrace();
    }

    @Override
    public void onComplete() {
        System.out.println("Done");
    }
});

由于命名冲突,把rx 包改成org.reactivestreams。此外org.reactivestreams.Subscriber 不能从外面添加、取消或请求。

为了弥补这一空缺,我们为Flowable定义了抽象类DefaultSubscriber, ResourceSubscriberDisposableSubscriber 分别提供了类似于rx.Subscriber的资源跟踪支持,并且可以从外面取消 dispose():

ResourceSubscriber<Integer> subscriber = new ResourceSubscriber<Integer>() {
    @Override
    public void onStart() {
        request(Long.MAX_VALUE);
    }

    @Override
    public void onNext(Integer t) {
        System.out.println(t);
    }

    @Override
    public void onError(Throwable t) {
        t.printStackTrace();
    }

    @Override
    public void onComplete() {
        System.out.println("Done");
    }
};

Flowable.range(1, 10).delay(1, TimeUnit.SECONDS).subscribe(subscriber);

subscriber.dispose();

注意,由于Reactive-Streams的兼容性,方法onCompleted被重命名为onComplete

因为1.x中,Observable.subscribe(Subscriber)返回Subscription,用户经常添加SubscriptionCompositeSubscription中,例如:

CompositeSubscription composite = new CompositeSubscription();

composite.add(Observable.range(1, 5).subscribe(new TestSubscriber<Integer>()));

由于Reactive-Streams规范,Publisher.subscribe无返回值。为了弥补这一点,我们增加了E subscribeWith(E subscriber)方法。因为在2.x中ResourceSubscriber 直接实现了Disposable,所以代码可以这样写。

CompositeDisposable composite2 = new CompositeDisposable();

composite2.add(Flowable.range(1, 5).subscribeWith(subscriber));

在onSubscribe/onStart中调用request

注意,在Subscriber.onSubscribeResourceSubscriber.onStart中调用request(n)将会立即调用onNext,实例代码如下:

Flowable.range(1, 3).subscribe(new Subscriber<Integer>() {

    @Override
    public void onSubscribe(Subscription s) {
        System.out.println("OnSubscribe start");
        s.request(Long.MAX_VALUE);
        System.out.println("OnSubscribe end");
    }

    @Override
    public void onNext(Integer v) {
        System.out.println(v);
    }

    @Override
    public void onError(Throwable e) {
        e.printStackTrace();
    }

    @Override
    public void onComplete() {
        System.out.println("Done");
    }
});

This will print:
将会打印:

OnSubscribe start
1
2
3
Done
OnSubscribe end

当你在onSubscribe/onStart中做了一些初始化的工作,而这些工作是在request后面时,会出现一些问题,在onNext执行时,你的初始化工作的那部分代码还没有执行。为了避免这种情况,请确保你调用request时,已经把所有初始化工作做完了。

这个行为不同于1.x中的 request要经过延迟的逻辑直到上游的Producer到达时。在2.x中,总是Subscription先传递下来,90%的情况下没有延迟请求的必要。

Subscription

在RxJava 1.x中,接口rx.Subscription负责流和资源的生命周期管理,即退订和释放资源,例如scheduled tasks。Reactive-Streams规范用这个名称指定source和consumer之间的关系: org.reactivestreams.Subscription 允许从上游请求一个正数,并支持取消。

为了避免名字冲突,1.x的rx.Subscription被改成了 io.reactivex.Disposable

因为Reactive-Streams的基础接口org.reactivestreams.Publisher 定义subscribe()为无返回值,Flowable.subscribe(Subscriber)不再返回任何Subscription。其他的基础类型也遵循这种规律。

在2.x中其他的subscribe的重载方法返回Disposable

原始的Subscription容器类型已经被重命名和修改。

  • CompositeSubscription 改成 CompositeDisposable
  • SerialSubscriptionMultipleAssignmentSubscription 被合并到了 SerialDisposableset() 方法取消了旧值,而replace()方法没有。
  • RefCountSubscription 已被删除。

背压

Reactive-Streams规范的操作符支持背压,特别是当它们不发送请求时,它们不会溢出。新的操作符Flowable被设计成适合下游请求,然而这个不意味着MissingBackpressureException不会出现。这个异常仍然存在。但这一次,onNext会抛出这个异常。

作为替代,在2.x中Observable完全不支持背压,但可以被替换。

Reactive-Streams compliance

Flowable-based sources和operators是遵从Reactive-Streams 1.0.0规范的,除了一个规则§3.9和解释的规则§1.3:

§3.9: While the Subscription is not cancelled, Subscription.request(long n) MUST signal onError with a java.lang.IllegalArgumentException if the argument is <= 0. The cause message MUST include a reference to this rule and/or quote the full rule.

Rule §3.9 requires excessive overhead to handle (half-serializer on every operator dealing with request()) for a bug-case. RxJava 2 (and Reactor 3 in fact) reports the IllegalArgumentException to RxJavaPlugins.onError and ignores it otherwise. RxJava 2 passes the Test Compatibility Kit (TCK) by applying a custom operator that routes the IllegalArgumentException into the Subscriber.onError in an async-safe manner. All major Reactive-Streams libraries are free of such zero requests; Reactor 3 ignores it as we do and Akka-Stream uses a converter (to interact with other RS sources and consumers) which has (probably) a similar routing behavior as our TCK operator.

§1.3: onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled sequentially (no concurrent notifications).

TCK 允许同步但限制onSubscribeonNext之间往返。也就是说在onSubscribe中,调用request(1)后将会调用onNext,在onNext返回后request(1)才会返回。虽然大部分操作符都是这样的,但操作符observeOn会异步的调用onNext,因此onSubscribe会和onNext同时被调用。这就是由TCK来检测,我们使用another operator来延迟下游请求直到onSubscribe返回。再次声明,这种异步行为不是RxJava 2的一个问题,因为在Reactor 3中操作符是线程安全的执行onSubscribe。Akka-Stream的转换类似于延迟请求。

因为这两个影响inter-library的行为,我们考虑在以后给Flowable增加了一个标准的操作符,把这两种行为改到一个单独的方法。

Runtime hooks

2.x 中重新设计了RxJavaPlugins类,现在支持运行时改变回调。测试需要重写schedulers,生命周期方法可以通过回调函数。

RxJavaObservableHook和友类现在都取消了,RxJavaHooks功能被加入到了RxJavaPlugins

Schedulers

在2.x的API中仍然支持主要的默认scheduler: computation, io, newThreadtrampoline,可以通过io.reactivex.schedulers.Schedulers这个实用的工具类来调度。

2.x中不存在immediate 调度器。 它被频繁的误用,并没有正常的实现 Scheduler 规范;它包含用于延迟动作的阻塞睡眠,并且不支持递归调度。你可以使用Schedulers.trampoline()来代替它。

Schedulers.test()已经被移除,这样避免了默认调度器休息的概念差异。那些返回一个”global”的调度器实例是鉴于test()总是返回一个新的TestScheduler实例。现在我们鼓励测试人员使用这样简单的代码new TestScheduler()

io.reactivex.Scheduler抽象类现在支持直接调度任务,不需要先创建然后通过Worker调度。

public abstract class Scheduler {

    public Disposable scheduleDirect(Runnable task) { ... }

    public Disposable scheduleDirect(Runnable task, long delay, TimeUnit unit) { ... }

    public Disposable scheduleDirectPeriodically(Runnable task, long initialDelay, 
        long period, TimeUnit unit) { ... }

    public long now(TimeUnit unit) { ... }

    // ... rest is the same: lifecycle methods, worker creation
}

主要的目的是为了避免跟踪Worker的开销。方法有一个默认的实现,你可以直接复用 createWorker ,但如果有需要,你也可以重写它来实现更强大的功能。

这些方法返回了当前时间调度器的概念, now()被改成接受一个用于指定单位量的TimeUnit的方法。

进入reactive的世界

RxJava 1.x的设计缺陷之一是暴露了rx.Observable.create()方法,该方法虽然很强大,但导致了你很少使用内置典型的操作符。不幸的是,有太多的代码依赖于这个库,所以我们不能删除或重命名它。

2.x是一个新的开始,我们不会再犯这个错误了。每一个基础类Flowable, Observable, Single, MaybeCompletable 都有安全的create操作符去支持背压和取消。

Flowable.create((FlowableEmitter<Integer> emitter) -> {
    emitter.onNext(1);
    emitter.onNext(2);
    emitter.onComplete();
}, BackpressureStrategy.BUFFER);

实际上,1.x中fromEmitter已经被重命名为Flowable.create。其他基础类型也有类似的create方法。

离开reactive的世界

除了subscribing 各自的consumers(Subscriber, Observer, SingleObserver, MaybeObserverCompletableObserver) 以及functional-interface 基础consumers(例如 subscribe(Consumer<T>, Consumer<Throwable>, Action)),以前在1.x中独立的BlockingObservable 已经集成了主要的基础类型。现在你可以直接调用blockingX来阻塞等待结果:

List<Integer> list = Flowable.range(1, 100).toList().blockingGet(); // toList() returns Single

Integer i = Flowable.range(100, 100).blockingLast();

在2.x中另外一个关于rx.Subscriberorg.reactivestreams.Subscriber重要的区别是,你的SubscriberObserver不允许抛出任何致命的异常。这意味着下面这样的代码不再是合法的:

Subscriber<Integer> subscriber = new Subscriber<Integer>() {
    @Override
    public void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE);
    }

    public void onNext(Integer t) {
        if (t == 1) {
            throw new IllegalArgumentException();
        }
    }

    public void onError(Throwable e) {
        if (e instanceof IllegalArgumentException) {
            throw new UnsupportedOperationException();
        }
    }

    public void onComplete() {
        throw new NoSuchElementException();
    }
};

Flowable.just(1).subscribe(subscriber);

这样的规则同样适用于Observer, SingleObserver, MaybeObserverCompletableObserver

由于很多现有基于1.x的代码做了类似的事情,我们设计了safeSubscribe方法来帮助你处理这样的代码。

当然你也可以使用subscribe(Consumer<T>, Consumer<Throwable>, Action)方法来提供一个回调。

Flowable.just(1)
.subscribe(
    subscriber::onNext, 
    subscriber::onError, 
    subscriber::onComplete, 
    subscriber::onSubscribe
);

Testing

测试RxJava 2.x和1.x中一样,Flowable可以用io.reactivex.subscribers.TestSubscriber测试,而非背压的Observable, Single, MaybeCompletable可以用io.reactivex.observers.TestObserver测试。

test() “operator”

为了支持我们内部测试,所有的基础类都有 test() 方法,返回TestSubscriberTestObserver:

TestSubscriber<Integer> ts = Flowable.range(1, 5).test();

TestObserver<Integer> to = Observable.range(1, 5).test();

TestObserver<Integer> tso = Single.just(1).test();

TestObserver<Integer> tmo = Maybe.just(1).test();

TestObserver<Integer> tco = Completable.complete().test();

第二个便利之处在于,大部分TestSubscriber/TestObserver方法返回自身实例,这让我们可以链式调用各种assertX方法。第三个便利是,你可以流畅的测试你的代码而不需要去创建或者引入TestSubscriber/TestObserver实例。

Flowable.range(1, 5)
.test()
.assertResult(1, 2, 3, 4, 5)
;

值得注意的新的断言方法

  • assertResult(T... items): 断言在onComplete中将会按指定顺序收到给定的值,并且没有错误。
  • assertFailure(Class<? extends Throwable> clazz, T... items): 断言将会收到指定的异常。
  • assertFailureAndMessage(Class<? extends Throwable> clazz, String message, T... items): 和assertFailure一样,但还会验证 getMessage() 中包含的值。
  • awaitDone(long time, TimeUnit unit) 等待一个终结事件,如果超时了,将会取消该事件。
  • assertOf(Consumer<TestSubscriber<T>> consumer) 组成一些断言到流式链中。

其中一个好处是,把Flowable改为Observable,所以测试代码不需要改变,内部的已经把TestSubscriber改成了TestObserver

提前取消和请求

TestObserver中的test()方法有一个 test(boolean cancel) 重载,它能在订阅前取消TestSubscriber/TestObserver:

PublishSubject<Integer> pp = PublishSubject.create();

// nobody subscribed yet
assertFalse(pp.hasSubscribers());

pp.test(true);

// nobody remained subscribed
assertFalse(pp.hasSubscribers());

TestSubscribertest(long initialRequest)test(long initialRequest, boolean cancel) 重载,用于指定初始请求数量以及TestSubscriber是否应该立即被取消。如果initialRequest被给定,TestSubscriber 实例通常需要被捕获以便访问request()方法:

PublishProcessor<Integer> pp = PublishProcessor.create();

TestSubscriber<Integer> ts = pp.test(0L);

ts.request(1);

pp.onNext(1);
pp.onNext(2);

ts.assertFailure(MissingBackpressureException.class, 1);

测试异步代码

对于给定的异步代码,流畅的阻塞终端事件是可能的:

Flowable.just(1)
.subscribeOn(Schedulers.single())
.test()
.awaitDone(5, TimeUnit.SECONDS)
.assertResult(1);

Mockito & TestSubscriber

那些在1.x中正在使用Mockito和Observer的用户需要去使用Subscriber.onSubscribe方法去提出初始的请求,否则序列化将会挂起或者失败:

@SuppressWarnings("unchecked")
public static <T> Subscriber<T> mockSubscriber() {
    Subscriber<T> w = mock(Subscriber.class);

    Mockito.doAnswer(new Answer<Object>() {
        @Override
        public Object answer(InvocationOnMock a) throws Throwable {
            Subscription s = a.getArgumentAt(0, Subscription.class);
            s.request(Long.MAX_VALUE);
            return null;
        }
    }).when(w).onSubscribe((Subscription)any());

    return w;
}

操作符的差别

2.x中大部分操作符仍然被保留,实际上大部分行为和1.x一样。下面的列表中列出了每一个基础类的在1.x和2.x的区别

通常来说,很多操作符提供了重载,允许指定运行上游的内部缓冲区的大小或者预先分配的数量。

一些操作符重载已经被重命名为了后缀风格,比如 fromArray, fromIterable。这么做的原因是,当用Java 8编译时,javac往往不能区分功能接口类型。

在1.x中被标记为@Beta@Experimental的操作符已经成为正式操作符了。

1.x Observable 到 2.x Flowable

工厂方法:

1.x 2.x
amb 添加 amb(ObservableSource...) 重载, 2-9 参数被删除
RxRingBuffer.SIZE bufferSize()
combineLatest 增加条目重载, 增加 带bufferSize 参数的重载, combineLatest(List) 被删除
concat 增加带 prefetch 参数的重载, 5-9 重载被删除 , 使用 concatArray 代替
N/A 增加 concatArrayconcatArrayDelayError
N/A 增加 concatArrayEagerconcatArrayEagerDelayError
concatDelayError 增加带延时的重载
concatEagerDelayError 增加带延时的重载
create(SyncOnSubscribe) generate + 重载代替
create(AsnycOnSubscribe) 不存在
create(OnSubscribe) 使用安全的 create(FlowableOnSubscribe, BackpressureStrategy), 支持 unsafeCreate()
from 拆分成 fromArray, fromIterable, fromFuture
N/A 增加 fromPublisher
fromAsync 重命名为 create()
N/A 增加 intervalRange()
limit 被删除, 使用 take
merge 增加带 prefetch的重载
mergeDelayError 增加带 prefetch的重载
sequenceEqual 增加带 bufferSize的重载
switchOnNext 增加带 prefetch的重载
switchOnNextDelayError 增加带 prefetch的重载
timer 被废弃
zip 增加带 bufferSizedelayErrors 的重载, 拆分成了 zipArrayzipIterable

实例方法:

1.x 2.x
all RC3 返回 Single<Boolean>
any RC3 返回 Single<Boolean>
asObservable 重命名为 hide(), 隐藏所有的身份
buffer 重载自定义的 Collection 提供者
cache(int) 被废弃
collect RC3 返回 Single<U>
collect(U, Action2<U, T>) 改成 collectIntoRC3 返回 Single<U>
concatMap 增加带 prefetch 的重载
concatMapDelayError 增加带 prefetch的重载, 支持延时
concatMapEager 增加带 prefetch的重载
concatMapEagerDelayError 增加带 prefetch的重载, 支持延时
count RC3 返回 Single<Long>
countLong 被删除, 使用 count
distinct 重载自定义的 Collection 提供者.
doOnCompleted 重命名为 doOnComplete
doOnUnsubscribe 重命名为 Flowable.doOnCanceldoOnDispose , additional info
N/A 增加 doOnLifecylce 来处理 onSubscribe, requestcancel
elementAt(int) RC3 不再发射 NoSuchElementException 如果源比索引更小
elementAt(Func1, int) 被删除, 使用 filter(predicate).elementAt(int) 代替
elementAtOrDefault(int, T) 重命名为 elementAt(int, T)RC3 返回 Single<T>
elementAtOrDefault(Func1, int, T) 被删除, 使用 filter(predicate).elementAt(int, T) 代替
first() RC3 重命名为 firstElement 返回 Maybe<T>
first(Func1) 被删除, 使用 filter(predicate).first()代替
firstOrDefault(T) 重命名为 first(T) RC3 返回 Single<T>
firstOrDefault(Func1, T) 被删除, 使用 filter(predicate).first(T)代替
flatMap 增加带 prefetch的重载
N/A 增加 forEachWhile(Predicate<T>, [Consumer<Throwable>, [Action]]) 用于有条件停止 consumption
groupBy 增加带 bufferSizedelayError的重载, 支持 支持内部自定义map,RC1中没有
ignoreElements RC3 返回 Completable
isEmpty RC3 返回 Single<Boolean>
last() RC3 重命名为 lastElement 返回 Maybe<T>
last(Func1) 被删除, 使用 filter(predicate).last()代替
lastOrDefault(T) 重命名为 last(T) RC3 返回 Single<T>
lastOrDefault(Func1, T) 被删除, 使用 filter(predicate).last(T)代替
nest 被删除, 使用 just代替
publish(Func1) 增加带 prefetch的重载
reduce(Func2) RC3 返回 Maybe<T>
N/A 增加 reduceWith(Callable, BiFunction) 为了减少自定义Subscriber, 返回 Single<T>
N/A 增加 repeatUntil(BooleanSupplier)
repeatWhen(Func1, Scheduler) 删除了重载, 使用 subscribeOn(Scheduler).repeatWhen(Function) 代替
retry 增加 retry(Predicate), retry(int, Predicate)
N/A 增加 retryUntil(BooleanSupplier)
retryWhen(Func1, Scheduler) 删除了重载, 使用 subscribeOn(Scheduler).retryWhen(Function) 代替
N/A 增加 sampleWith(Callable, BiFunction) 去扫描自定义的Subscriber方式
single() RC3 重命名为 singleElement 返回 Maybe<T>
single(Func1) 被删除,使用 filter(predicate).single()代替
singleOrDefault(T) 重命名为 single(T) RC3 返回 Single<T>
singleOrDefault(Func1, T) 被删除,使用 filter(predicate).single(T)代替
skipLast 增加带 bufferSizedelayError 的重载
startWith 2-9 参数的被删除了, 使用 startWithArray 代替
N/A 增加 startWithArray 来减少二义性
N/A 增加 subscribeWith 返回输入的订阅对象
switchMap 增加带 prefetch 的重载
switchMapDelayError 增加带 prefetch 的重载
takeLastBuffer 被删除
N/A 增加 test()
timeout(Func0<Observable>, ...) 方法签名改成了 timeout(Publisher, ...) 删除了方法, 如果有需要,使用 defer(Callable<Publisher>>)
toBlocking().y 内联 blockingY() 操作符, 除了 toFuture
toCompletable RC3 被删除, 使用 ignoreElements代替
toList RC3 返回 Single<List<T>>
toMap RC3 返回 Single<Map<K, V>>
toMultimap RC3 返回 Single<Map<K, Collection<V>>>
N/A 增加 toFuture
N/A 增加 toObservable
toSingle RC3 被删除, 使用 single(T)代替
toSortedList RC3 增加 Single<List<T>>
withLatestFrom 5-9 个参数的重载被删除
zipWith 增加带 prefetchdelayErrors 的重载

不同的返回类型

2.x中一些的操作符产生确切的一个值或者一个错误时,返回Single

操作符 旧返回值 新返回值 备注
all(Predicate) Observable<Boolean> Single<Boolean> 如果所有的元素都匹配,则发射true
any(Predicate) Observable<Boolean> Single<Boolean> 如果所有的元素都匹配,则发射true
count() Observable<Long> Single<Long> 计算序列中元素的数量
elementAt(int) Observable<T> Maybe<T> Emits 给定位置处的元素或完成的元素
elementAt(int, T) Observable<T> Single<T> 发射指定位置的元素或默认元素
first(T) Observable<T> Single<T> 发射第一个元素或者抛出 NoSuchElementException
firstElement() Observable<T> Maybe<T> 发射第一个元素或者结束
ignoreElements() Observable<T> Completable 忽略所有非终端事件
isEmpty() Observable<Boolean> Single<Boolean> 如果源为空,则发射true
last(T) Observable<T> Single<T> 发射最后一个元素或默认值
lastElement() Observable<T> Maybe<T> 发射最后一个元素或结束
reduce(BiFunction) Observable<T> Maybe<T> 发射减少的值或者结束
reduce(Callable, BiFunction) Observable<U> Single<U> 发射减少的值或者初始的值
reduceWith(U, BiFunction) Observable<U> Single<U> 发射减少的值或者初始的值
single(T) Observable<T> Single<T> 发射唯一的元素或默认值
singleElement() Observable<T> Maybe<T> 发射唯一的元素或结束
toList() Observable<List<T>> Single<List<T>> 将所有元素放到 List
toMap() Observable<Map<K, V>> Single<Map<K, V>> 将所有元素放到 Map
toMultimap() Observable<Map<K, Collection<V>>> Single<Map<K, Collection<V>>> 将所有元素包装到Collection后放到 Map
toSortedList() Observable<List<T>> Single<List<T>> 将所有元素放到 List 并排序

移除

为了保证最终的2.0API尽可能干净,我们删除了一些候选的方法和组件。

删除时的版本 组件 备注
RC3 Flowable.toCompletable() 使用 Flowable.ignoreElements()代替
RC3 Flowable.toSingle() 使用 Flowable.single(T)代替
RC3 Flowable.toMaybe() 使用 Flowable.singleElement()代替
RC3 Observable.toCompletable() 使用 Observable.ignoreElements()代替
RC3 Observable.toSingle() 使用 Observable.single(T)代替
RC3 Observable.toMaybe() 使用 Observable.singleElement()代替

其他改变

doOnCancel/doOnDispose/unsubscribeOn

在1.x中,doOnUnsubscribe总是执行终端事件,因为SafeSubscriber调用了unsubscribe。这实际上是没有必要的。Reactive-Streams规范中,一个终端事件到达Subscriber,上游的Subscription会取消,因此调用 cancel()是一个空操作。

由于同样的原因unsubscribeOn也没被在终端路径上调用,但只有实际在链上调用cancel时,才会调用unsubscribeOn

因此,下面的序列不会被调用
doOnCancel:

Flowable.just(1, 2, 3)
.doOnCancel(() -> System.out.println("Cancelled!"))
.subscribe(System.out::println);

然而,下面将会调用take操作符在传送过程中取消onNext

Flowable.just(1, 2, 3)
.doOnCancel(() -> System.out.println("Cancelled!"))
.take(2)
.subscribe(System.out::println);

如果你需要在终端或者取消时执行清理,考虑使用using操作符代替。

猜你喜欢

转载自blog.csdn.net/qq_35064774/article/details/53045298