rx.Single Maven / Gradle / Ivy
/**
* Copyright 2015 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
* the License for the specific language governing permissions and limitations under the License.
*/
package rx;
import java.util.Collection;
import java.util.concurrent.*;
import rx.Observable.Operator;
import rx.annotations.*;
import rx.exceptions.*;
import rx.functions.*;
import rx.internal.observers.AssertableSubscriberObservable;
import rx.internal.operators.*;
import rx.internal.util.*;
import rx.observables.ConnectableObservable;
import rx.observers.*;
import rx.plugins.RxJavaHooks;
import rx.schedulers.Schedulers;
import rx.singles.BlockingSingle;
import rx.subscriptions.Subscriptions;
/**
* The Single class implements the Reactive Pattern for a single value response. See {@link Observable} for the
* implementation of the Reactive Pattern for a stream or vector of values.
*
* {@code Single} behaves the same as {@link Observable} except that it can only emit either a single successful
* value, or an error (there is no "onComplete" notification as there is for {@link Observable})
*
* Like an {@link Observable}, a {@code Single} is lazy, can be either "hot" or "cold", synchronous or
* asynchronous.
*
* The documentation for this class makes use of marble diagrams. The following legend explains these diagrams:
*
*
*
* For more information see the ReactiveX
* documentation.
*
* @param
* the type of the item emitted by the Single
* @since 1.2
*/
public class Single {
final OnSubscribe onSubscribe;
/**
* Creates a Single with a Function to execute when it is subscribed to (executed).
*
* Note: Use {@link #create(OnSubscribe)} to create a Single, instead of this constructor,
* unless you specifically have a need for inheritance.
*
* @param f
* {@code f} to be executed when {@code execute(SingleSubscriber)} or
* {@code subscribe(Subscriber)} is called
*/
protected Single(OnSubscribe f) {
this.onSubscribe = RxJavaHooks.onCreate(f);
}
/**
* Creates a Single with a Function to execute when it is subscribed to (executed).
*
* Note: Use {@link #create(OnSubscribe)} to create a Single, instead of this constructor,
* unless you specifically have a need for inheritance.
*
* @param f
* {@code f} to be executed when {@code execute(SingleSubscriber)} or
* {@code subscribe(Subscriber)} is called
* @deprecated 1.2.1: Not recommended, use {@link #Single(OnSubscribe)} to avoid wrapping and
* conversion between the Observable and Single protocols.
*/
@Deprecated
protected Single(final Observable.OnSubscribe f) {
onSubscribe = RxJavaHooks.onCreate(new SingleFromObservable(f));
}
/**
* Returns a Single that will execute the specified function when a {@link SingleSubscriber} executes it or
* a {@link Subscriber} subscribes to it.
*
*
*
* Write the function you pass to {@code create} so that it behaves as a Single: It should invoke the
* SingleSubscriber {@link SingleSubscriber#onSuccess onSuccess} and/or
* {@link SingleSubscriber#onError onError} methods appropriately.
*
* A well-formed Single must invoke either the SingleSubscriber's {@code onSuccess} method exactly once or
* its {@code onError} method exactly once.
*
*
* - Scheduler:
* - {@code create} does not operate by default on a particular {@link Scheduler}.
*
*
* @param
* the type of the item that this Single emits
* @param f
* a function that accepts an {@code SingleSubscriber}, and invokes its {@code onSuccess} or
* {@code onError} methods as appropriate
* @return a Single that, when a {@link Subscriber} subscribes to it, will execute the specified function
* @see ReactiveX operators documentation: Create
*/
public static Single create(OnSubscribe f) {
return new Single(f);
}
/**
* Invoked when Single.execute is called.
* @param the output value type
*/
public interface OnSubscribe extends Action1> {
// cover for generics insanity
}
/**
* Lifts a function to the current Single and returns a new Single that when subscribed to will pass the
* values of the current Single through the Operator function.
*
* In other words, this allows chaining TaskExecutors together on a Single for acting on the values within
* the Single.
*
* {@code task.map(...).filter(...).lift(new OperatorA()).lift(new OperatorB(...)).subscribe() }
*
* If the operator you are creating is designed to act on the item emitted by a source Single, use
* {@code lift}. If your operator is designed to transform the source Single as a whole (for instance, by
* applying a particular set of existing RxJava operators to it) use {@link #compose}.
*
* - Scheduler:
* - {@code lift} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the downstream's value type (output)
* @param lift
* the Operator that implements the Single-operating function to be applied to the source Single
* @return a Single that is the result of applying the lifted Operator to the source Single
* @see RxJava wiki: Implementing Your Own Operators
* @since 1.3
*/
public final Single lift(final Operator extends R, ? super T> lift) {
return create(new SingleLiftObservableOperator(this.onSubscribe, lift));
}
/**
* Transform a Single by applying a particular Transformer function to it.
*
* This method operates on the Single itself whereas {@link #lift} operates on the Single's Subscribers or
* Observers.
*
* If the operator you are creating is designed to act on the individual item emitted by a Single, use
* {@link #lift}. If your operator is designed to transform the source Single as a whole (for instance, by
* applying a particular set of existing RxJava operators to it) use {@code compose}.
*
* - Scheduler:
* - {@code compose} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the value type of the single returned by the transformer function
* @param transformer
* implements the function that transforms the source Single
* @return the source Single, transformed by the transformer function
* @see RxJava wiki: Implementing Your Own Operators
*/
@SuppressWarnings("unchecked")
public Single compose(Transformer super T, ? extends R> transformer) {
return ((Transformer) transformer).call(this);
}
/**
* Convenience type that allows a function to fluently transform a
* Single into another Single via {@link #compose}.
*
* Transformer<Integer, Integer> transformer = s ->
* s.subscribeOn(Schedulers.io())
* .observeOn(AndroidSchedulers.mainThread());
*
* Single.just(1)
* .compose(transformer)
* .subscribe(System.out::println);
*
*
* @param the source Single's value type
* @param the transformed Single's value type
*/
public interface Transformer extends Func1, Single> {
// cover for generics insanity
}
/**
* Hides the identity of this Single.
*
*/
private static Observable asObservable(Single t) {
// is this sufficient, or do I need to keep the outer Single and subscribe to it?
return Observable.unsafeCreate(new SingleToObservable(t.onSubscribe));
}
/* *********************************************************************************************************
* Operators Below Here
* *********************************************************************************************************
*/
/**
* Casts the success value of the current Single into the target type or signals a
* ClassCastException if not compatible.
*
* - Scheduler:
* - {@code cast} does not operate by default on a particular {@link Scheduler}.
*
* @param the target type
* @param klass the type token to use for casting the success result from the current Single
* @return the new Single instance
* @since 1.3.1 - experimental
*/
@Experimental
public final Single cast(final Class klass) {
return map(new SingleOperatorCast(klass));
}
/**
* Returns an Observable that emits the items emitted by two Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @return an Observable that emits items emitted by the two source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2) {
return Observable.concat(asObservable(t1), asObservable(t2));
}
/**
* Returns an Observable that emits the items emitted by three Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @param t3
* a Single to be concatenated
* @return an Observable that emits items emitted by the three source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2, Single extends T> t3) {
return Observable.concat(asObservable(t1), asObservable(t2), asObservable(t3));
}
/**
* Returns an Observable that emits the items emitted by four Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @param t3
* a Single to be concatenated
* @param t4
* a Single to be concatenated
* @return an Observable that emits items emitted by the four source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4) {
return Observable.concat(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4));
}
/**
* Returns an Observable that emits the items emitted by five Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @param t3
* a Single to be concatenated
* @param t4
* a Single to be concatenated
* @param t5
* a Single to be concatenated
* @return an Observable that emits items emitted by the five source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5) {
return Observable.concat(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5));
}
/**
* Returns an Observable that emits the items emitted by six Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @param t3
* a Single to be concatenated
* @param t4
* a Single to be concatenated
* @param t5
* a Single to be concatenated
* @param t6
* a Single to be concatenated
* @return an Observable that emits items emitted by the six source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6) {
return Observable.concat(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6));
}
/**
* Returns an Observable that emits the items emitted by seven Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @param t3
* a Single to be concatenated
* @param t4
* a Single to be concatenated
* @param t5
* a Single to be concatenated
* @param t6
* a Single to be concatenated
* @param t7
* a Single to be concatenated
* @return an Observable that emits items emitted by the seven source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6, Single extends T> t7) {
return Observable.concat(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6), asObservable(t7));
}
/**
* Returns an Observable that emits the items emitted by eight Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @param t3
* a Single to be concatenated
* @param t4
* a Single to be concatenated
* @param t5
* a Single to be concatenated
* @param t6
* a Single to be concatenated
* @param t7
* a Single to be concatenated
* @param t8
* a Single to be concatenated
* @return an Observable that emits items emitted by the eight source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6, Single extends T> t7, Single extends T> t8) {
return Observable.concat(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6), asObservable(t7), asObservable(t8));
}
/**
* Returns an Observable that emits the items emitted by nine Singles, one after the other.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be concatenated
* @param t2
* a Single to be concatenated
* @param t3
* a Single to be concatenated
* @param t4
* a Single to be concatenated
* @param t5
* a Single to be concatenated
* @param t6
* a Single to be concatenated
* @param t7
* a Single to be concatenated
* @param t8
* a Single to be concatenated
* @param t9
* a Single to be concatenated
* @return an Observable that emits items emitted by the nine source Singles, one after the other.
* @see ReactiveX operators documentation: Concat
*/
public static Observable concat(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6, Single extends T> t7, Single extends T> t8, Single extends T> t9) {
return Observable.concat(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6), asObservable(t7), asObservable(t8), asObservable(t9));
}
/**
* Returns a Single that invokes a subscriber's {@link SingleSubscriber#onError onError} method when the
* subscriber subscribes to it.
*
*
*
* - Scheduler:
* - {@code error} does not operate by default on a particular {@link Scheduler}.
*
*
* @param exception
* the particular Throwable to pass to {@link SingleSubscriber#onError onError}
* @param
* the type of the item (ostensibly) emitted by the Single
* @return a Single that invokes the subscriber's {@link SingleSubscriber#onError onError} method when
* the subscriber subscribes to it
* @see ReactiveX operators documentation: Throw
*/
public static Single error(final Throwable exception) {
return Single.create(new OnSubscribe() {
@Override
public void call(SingleSubscriber super T> te) {
te.onError(exception);
}
});
}
/**
* Converts a {@link Future} into a {@code Single}.
*
*
*
* You can convert any object that supports the {@link Future} interface into a Single that emits the return
* value of the {@link Future#get} method of that object, by passing the object into the {@code from}
* method.
*
* Important note: This Single is blocking; you cannot unsubscribe from it.
*
* - Scheduler:
* - {@code from} does not operate by default on a particular {@link Scheduler}.
*
*
* @param future
* the source {@link Future}
* @param
* the type of object that the {@link Future} returns, and also the type of item to be emitted by
* the resulting {@code Single}
* @return a {@code Single} that emits the item from the source {@link Future}
* @see ReactiveX operators documentation: From
*/
public static Single from(Future extends T> future) {
return create(new SingleFromFuture(future, 0, null));
}
/**
* Converts a {@link Future} into a {@code Single}, with a timeout on the Future.
*
*
*
* You can convert any object that supports the {@link Future} interface into a {@code Single} that emits
* the return value of the {@link Future#get} method of that object, by passing the object into the
* {@code from} method.
*
* Important note: This {@code Single} is blocking; you cannot unsubscribe from it.
*
* - Scheduler:
* - {@code from} does not operate by default on a particular {@link Scheduler}.
*
*
* @param future
* the source {@link Future}
* @param timeout
* the maximum time to wait before calling {@code get}
* @param unit
* the {@link TimeUnit} of the {@code timeout} argument
* @param
* the type of object that the {@link Future} returns, and also the type of item to be emitted by
* the resulting {@code Single}
* @return a {@code Single} that emits the item from the source {@link Future}
* @see ReactiveX operators documentation: From
*/
public static Single from(Future extends T> future, long timeout, TimeUnit unit) {
if (unit == null) {
throw new NullPointerException("unit is null");
}
return create(new SingleFromFuture(future, timeout, unit));
}
/**
* Converts a {@link Future}, operating on a specified {@link Scheduler}, into a {@code Single}.
*
*
*
* You can convert any object that supports the {@link Future} interface into a {@code Single} that emits
* the return value of the {@link Future#get} method of that object, by passing the object into the
* {@code from} method.
*
* - Scheduler:
* - you specify which {@link Scheduler} this operator will use
*
*
* @param future
* the source {@link Future}
* @param scheduler
* the {@link Scheduler} to wait for the Future on. Use a Scheduler such as
* {@link Schedulers#io()} that can block and wait on the Future
* @param
* the type of object that the {@link Future} returns, and also the type of item to be emitted by
* the resulting {@code Single}
* @return a {@code Single} that emits the item from the source {@link Future}
* @see ReactiveX operators documentation: From
*/
public static Single from(Future extends T> future, Scheduler scheduler) {
return from(future).subscribeOn(scheduler);
}
/**
* Returns a {@link Single} that invokes passed function and emits its result for each new Observer that subscribes.
*
* Allows you to defer execution of passed function until Observer subscribes to the {@link Single}.
* It makes passed function "lazy".
* Result of the function invocation will be emitted by the {@link Single}.
*
* - Scheduler:
* - {@code fromCallable} does not operate by default on a particular {@link Scheduler}.
*
*
* @param func
* function which execution should be deferred, it will be invoked when Observer will subscribe to the {@link Single}.
* @param
* the type of the item emitted by the {@link Single}.
* @return a {@link Single} whose {@link Observer}s' subscriptions trigger an invocation of the given function.
*/
public static Single fromCallable(final Callable extends T> func) {
return create(new SingleFromCallable(func));
}
/**
* Provides an API (in a cold Single) that bridges the Single-reactive world
* with the callback-based world.
* The {@link SingleEmitter} allows registering a callback for
* cancellation/unsubscription of a resource.
*
* Example:
*
* Single.fromEmitter(emitter -> {
* Callback listener = new Callback() {
* @Override
* public void onEvent(Event e) {
* emitter.onSuccess(e.getData());
* }
*
* @Override
* public void onFailure(Exception e) {
* emitter.onError(e);
* }
* };
*
* AutoCloseable c = api.someMethod(listener);
*
* emitter.setCancellation(c::close);
*
* });
*
* All of the SingleEmitter's methods are thread-safe and ensure the
* Single's protocol are held.
*
History: 1.2.3 - experimental
* @param the success value type
* @param producer the callback invoked for each incoming SingleSubscriber
* @return the new Single instance
* @since 1.3
*/
public static Single fromEmitter(Action1> producer) {
if (producer == null) { throw new NullPointerException("producer is null"); }
return create(new SingleFromEmitter(producer));
}
/**
* Returns a {@code Single} that emits a specified item.
*
*
*
* To convert any object into a {@code Single} that emits that object, pass that object into the
* {@code just} method.
*
* - Scheduler:
* - {@code just} does not operate by default on a particular {@link Scheduler}.
*
*
* @param value
* the item to emit
* @param
* the type of that item
* @return a {@code Single} that emits {@code value}
* @see ReactiveX operators documentation: Just
*/
public static Single just(final T value) {
return ScalarSynchronousSingle.create(value);
}
/**
* Flattens a {@code Single} that emits a {@code Single} into a single {@code Single} that emits the item
* emitted by the nested {@code Single}, without any transformation.
*
*
*
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the value type of the sources and the output
* @param source
* a {@code Single} that emits a {@code Single}
* @return a {@code Single} that emits the item that is the result of flattening the {@code Single} emitted
* by {@code source}
* @see ReactiveX operators documentation: Merge
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Single merge(final Single extends Single extends T>> source) {
if (source instanceof ScalarSynchronousSingle) {
return ((ScalarSynchronousSingle) source).scalarFlatMap((Func1) UtilityFunctions.identity());
}
return Single.create(new OnSubscribe() {
@Override
public void call(final SingleSubscriber super T> child) {
SingleSubscriber> parent = new SingleSubscriber>() {
@Override
public void onSuccess(Single extends T> innerSingle) {
innerSingle.subscribe(child);
}
@Override
public void onError(Throwable error) {
child.onError(error);
}
};
child.add(parent);
source.subscribe(parent);
}
});
}
/**
* Flattens two Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by
* using the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2) {
return Observable.merge(asObservable(t1), asObservable(t2));
}
/**
* Flattens three Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @param t3
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2, Single extends T> t3) {
return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3));
}
/**
* Flattens four Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @param t3
* a Single to be merged
* @param t4
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4) {
return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4));
}
/**
* Flattens five Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @param t3
* a Single to be merged
* @param t4
* a Single to be merged
* @param t5
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5) {
return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5));
}
/**
* Flattens six Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @param t3
* a Single to be merged
* @param t4
* a Single to be merged
* @param t5
* a Single to be merged
* @param t6
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6) {
return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6));
}
/**
* Flattens seven Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @param t3
* a Single to be merged
* @param t4
* a Single to be merged
* @param t5
* a Single to be merged
* @param t6
* a Single to be merged
* @param t7
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6, Single extends T> t7) {
return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6), asObservable(t7));
}
/**
* Flattens eight Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @param t3
* a Single to be merged
* @param t4
* a Single to be merged
* @param t5
* a Single to be merged
* @param t6
* a Single to be merged
* @param t7
* a Single to be merged
* @param t8
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6, Single extends T> t7, Single extends T> t8) {
return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6), asObservable(t7), asObservable(t8));
}
/**
* Flattens nine Singles into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code merge} method.
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param t1
* a Single to be merged
* @param t2
* a Single to be merged
* @param t3
* a Single to be merged
* @param t4
* a Single to be merged
* @param t5
* a Single to be merged
* @param t6
* a Single to be merged
* @param t7
* a Single to be merged
* @param t8
* a Single to be merged
* @param t9
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public static Observable merge(Single extends T> t1, Single extends T> t2, Single extends T> t3, Single extends T> t4, Single extends T> t5, Single extends T> t6, Single extends T> t7, Single extends T> t8, Single extends T> t9) {
return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6), asObservable(t7), asObservable(t8), asObservable(t9));
}
/**
* Merges all Singles emitted by the Observable and runs them together until the source
* Observable and all inner Singles complete normally.
*
* - Backpressure:
* - The operator consumes items from the Observable in an unbounded manner and honors downstream backpressure.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
* History: 1.2.7 - experimental
* @param the value type of the inner Singles and the resulting Observable
* @param sources the Observable that emits Singles to be merged
* @return the new Observable instance
* @see #merge(Observable, int)
* @see #mergeDelayError(Observable)
* @see #mergeDelayError(Observable, int)
* @since 1.3
*/
public static Observable merge(Observable extends Single extends T>> sources) {
return merge(sources, Integer.MAX_VALUE);
}
/**
* Merges the Singles emitted by the Observable and runs up to the given number of them together at a time,
* until the Observable and all inner Singles terminate.
*
* - Backpressure:
* - The operator consumes at most maxConcurrent items from the Observable and one-by-one after as the inner
* Singles terminate. The operator ignores downstream backpressure as it doesn't emit items but
* only the terminal event.
* - Scheduler:
* - {@code flatMapSingle} does not operate by default on a particular {@link Scheduler}.
*
* History: 1.2.7 - experimental
* @param the value type of the inner Singles and the resulting Observable
* @param sources the Observable that emits Singles to be merged
* @param maxConcurrency the maximum number of inner Singles to run at a time
* @return the new Observable instance
* @since 1.3
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Observable merge(Observable extends Single extends T>> sources, int maxConcurrency) {
return sources.flatMapSingle((Func1)UtilityFunctions.identity(), false, maxConcurrency);
}
/**
* Merges all Singles emitted by the Observable and runs them together,
* delaying errors from them and the Observable, until the source
* Observable and all inner Singles complete normally.
*
* - Backpressure:
* - The operator consumes items from the Observable in an unbounded manner and honors downstream backpressure.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
*
* History: 1.2.7 - experimental
* @param the value type of the inner Singles and the resulting Observable
* @param sources the Observable that emits Singles to be merged
* @return the new Observable instance
* @see #mergeDelayError(Observable, int)
* @see #merge(Observable)
* @see #merge(Observable, int)
* @since 1.3
*/
public static Observable mergeDelayError(Observable extends Single extends T>> sources) {
return merge(sources, Integer.MAX_VALUE);
}
/**
* Merges the Singles emitted by the Observable and runs up to the given number of them together at a time,
* delaying errors from them and the Observable, until the Observable and all inner Singles terminate.
*
* - Backpressure:
* - The operator consumes at most maxConcurrent items from the Observable and one-by-one after as the inner
* Singles terminate. The operator ignores downstream backpressure as it doesn't emit items but
* only the terminal event.
* - Scheduler:
* - {@code flatMapSingle} does not operate by default on a particular {@link Scheduler}.
*
* History: 1.2.7 - experimental
* @param the value type of the inner Singles and the resulting Observable
* @param sources the Observable that emits Singles to be merged
* @param maxConcurrency the maximum number of inner Singles to run at a time
* @return the new Observable instance
* @since 1.3
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Observable mergeDelayError(Observable extends Single extends T>> sources, int maxConcurrency) {
return sources.flatMapSingle((Func1)UtilityFunctions.identity(), true, maxConcurrency);
}
/**
* Returns a Single that emits the results of a specified combiner function applied to two items emitted by
* two other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, final Func2 super T1, ? super T2, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1]);
}
});
}
/**
* Returns a Single that emits the results of a specified combiner function applied to three items emitted
* by three other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the third source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param s3
* a third source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, Single extends T3> s3, final Func3 super T1, ? super T2, ? super T3, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2, s3}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1], (T3) args[2]);
}
});
}
/**
* Returns an Observable that emits the results of a specified combiner function applied to four items
* emitted by four other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the third source Single's value type
* @param the fourth source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param s3
* a third source Single
* @param s4
* a fourth source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, Single extends T3> s3, Single extends T4> s4, final Func4 super T1, ? super T2, ? super T3, ? super T4, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2, s3, s4}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1], (T3) args[2], (T4) args[3]);
}
});
}
/**
* Returns an Observable that emits the results of a specified combiner function applied to five items
* emitted by five other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the third source Single's value type
* @param the fourth source Single's value type
* @param the fifth source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param s3
* a third source Single
* @param s4
* a fourth source Single
* @param s5
* a fifth source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, Single extends T3> s3, Single extends T4> s4, Single extends T5> s5, final Func5 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2, s3, s4, s5}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1], (T3) args[2], (T4) args[3], (T5) args[4]);
}
});
}
/**
* Returns an Observable that emits the results of a specified combiner function applied to six items
* emitted by six other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the third source Single's value type
* @param the fourth source Single's value type
* @param the fifth source Single's value type
* @param the sixth source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param s3
* a third source Single
* @param s4
* a fourth source Single
* @param s5
* a fifth source Single
* @param s6
* a sixth source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, Single extends T3> s3, Single extends T4> s4, Single extends T5> s5, Single extends T6> s6,
final Func6 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2, s3, s4, s5, s6}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1], (T3) args[2], (T4) args[3], (T5) args[4], (T6) args[5]);
}
});
}
/**
* Returns an Observable that emits the results of a specified combiner function applied to seven items
* emitted by seven other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the third source Single's value type
* @param the fourth source Single's value type
* @param the fifth source Single's value type
* @param the sixth source Single's value type
* @param the seventh source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param s3
* a third source Single
* @param s4
* a fourth source Single
* @param s5
* a fifth source Single
* @param s6
* a sixth source Single
* @param s7
* a seventh source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, Single extends T3> s3, Single extends T4> s4, Single extends T5> s5, Single extends T6> s6, Single extends T7> s7,
final Func7 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2, s3, s4, s5, s6, s7}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1], (T3) args[2], (T4) args[3], (T5) args[4], (T6) args[5], (T7) args[6]);
}
});
}
/**
* Returns an Observable that emits the results of a specified combiner function applied to eight items
* emitted by eight other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the third source Single's value type
* @param the fourth source Single's value type
* @param the fifth source Single's value type
* @param the sixth source Single's value type
* @param the seventh source Single's value type
* @param the eighth source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param s3
* a third source Single
* @param s4
* a fourth source Single
* @param s5
* a fifth source Single
* @param s6
* a sixth source Single
* @param s7
* a seventh source Single
* @param s8
* an eighth source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, Single extends T3> s3, Single extends T4> s4, Single extends T5> s5, Single extends T6> s6, Single extends T7> s7, Single extends T8> s8,
final Func8 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2, s3, s4, s5, s6, s7, s8}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1], (T3) args[2], (T4) args[3], (T5) args[4], (T6) args[5], (T7) args[6], (T8) args[7]);
}
});
}
/**
* Returns an Observable that emits the results of a specified combiner function applied to nine items
* emitted by nine other Singles.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source Single's value type
* @param the second source Single's value type
* @param the third source Single's value type
* @param the fourth source Single's value type
* @param the fifth source Single's value type
* @param the sixth source Single's value type
* @param the seventh source Single's value type
* @param the eighth source Single's value type
* @param the ninth source Single's value type
* @param the result value type
* @param s1
* the first source Single
* @param s2
* a second source Single
* @param s3
* a third source Single
* @param s4
* a fourth source Single
* @param s5
* a fifth source Single
* @param s6
* a sixth source Single
* @param s7
* a seventh source Single
* @param s8
* an eighth source Single
* @param s9
* a ninth source Single
* @param zipFunction
* a function that, when applied to the item emitted by each of the source Singles, results in an
* item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Single extends T1> s1, Single extends T2> s2, Single extends T3> s3, Single extends T4> s4, Single extends T5> s5, Single extends T6> s6, Single extends T7> s7, Single extends T8> s8,
Single extends T9> s9, final Func9 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? extends R> zipFunction) {
return SingleOperatorZip.zip(new Single[] {s1, s2, s3, s4, s5, s6, s7, s8, s9}, new FuncN() {
@Override
public R call(Object... args) {
return zipFunction.call((T1) args[0], (T2) args[1], (T3) args[2], (T4) args[3], (T5) args[4], (T6) args[5], (T7) args[6], (T8) args[7], (T9) args[8]);
}
});
}
/**
* Returns a Single that emits the result of specified combiner function applied to combination of
* items emitted, in sequence, by an Iterable of other Singles.
*
* {@code zip} applies this function in strict sequence.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the result value type
* @param singles
* an Iterable of source Singles. Should not be empty because {@link Single} either emits result or error.
* {@link java.util.NoSuchElementException} will be emit as error if Iterable will be empty.
* @param zipFunction
* a function that, when applied to an item emitted by each of the source Singles, results in
* an item that will be emitted by the resulting Single
* @return a Single that emits the zipped results
* @see ReactiveX operators documentation: Zip
*/
@SuppressWarnings("unchecked")
public static Single zip(Iterable extends Single>> singles, FuncN extends R> zipFunction) {
@SuppressWarnings("rawtypes")
Single[] iterableToArray = iterableToArray(singles);
return SingleOperatorZip.zip(iterableToArray, zipFunction);
}
/**
* Returns a Single that subscribes to this Single lazily, caches its success or error event
* and replays it to all the downstream subscribers.
*
*
*
* This is useful when you want a Single to cache its response and you can't control the
* subscribe/unsubscribe behavior of all the {@link Subscriber}s.
*
* The operator subscribes only when the first downstream subscriber subscribes and maintains
* a single subscription towards this Single. In contrast, the operator family of {@link Observable#replay()}
* that return a {@link ConnectableObservable} require an explicit call to {@link ConnectableObservable#connect()}.
*
* Note: You sacrifice the ability to unsubscribe from the origin when you use the {@code cache}
* Observer so be careful not to use this Observer on Observables that emit an infinite or very large number
* of items that will use up memory.
* A possible workaround is to apply `takeUntil` with a predicate or
* another source before (and perhaps after) the application of cache().
*
* AtomicBoolean shouldStop = new AtomicBoolean();
*
* source.takeUntil(v -> shouldStop.get())
* .cache()
* .takeUntil(v -> shouldStop.get())
* .subscribe(...);
*
* Since the operator doesn't allow clearing the cached values either, the possible workaround is
* to forget all references to it via {@link Observable#onTerminateDetach()} applied along with the previous
* workaround:
*
* AtomicBoolean shouldStop = new AtomicBoolean();
*
* source.takeUntil(v -> shouldStop.get())
* .onTerminateDetach()
* .cache()
* .takeUntil(v -> shouldStop.get())
* .onTerminateDetach()
* .subscribe(...);
*
*
* - Backpressure:
* - The operator consumes this Single in an unbounded fashion but respects the backpressure
* of each downstream Subscriber individually.
* - Scheduler:
* - {@code cache} does not operate by default on a particular {@link Scheduler}.
*
*
* @return a Single that, when first subscribed to, caches its response for the
* benefit of subsequent subscribers
* @see ReactiveX operators documentation: Replay
* @since 1.3
*/
public final Single cache() {
return toObservable().cacheWithInitialCapacity(1).toSingle();
}
/**
* Returns an Observable that emits the item emitted by the source Single, then the item emitted by the
* specified Single.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param t1
* a Single to be concatenated after the current
* @return an Observable that emits the item emitted by the source Single, followed by the item emitted by
* {@code t1}
* @see ReactiveX operators documentation: Concat
*/
public final Observable concatWith(Single extends T> t1) {
return concat(this, t1);
}
/**
* Returns a Single that is based on applying a specified function to the item emitted by the source Single,
* where that function returns a Single.
*
*
*
* - Scheduler:
* - {@code flatMap} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the result value type
* @param func
* a function that, when applied to the item emitted by the source Single, returns a Single
* @return the Single returned from {@code func} when applied to the item emitted by the source Single
* @see ReactiveX operators documentation: FlatMap
*/
public final Single flatMap(final Func1 super T, ? extends Single extends R>> func) {
if (this instanceof ScalarSynchronousSingle) {
return ((ScalarSynchronousSingle) this).scalarFlatMap(func);
}
return merge(map(func));
}
/**
* Returns an Observable that emits items based on applying a specified function to the item emitted by the
* source Observable, where that function returns an Observable.
*
*
*
* - Scheduler:
* - {@code flatMapObservable} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the result value type
* @param func
* a function that, when applied to the item emitted by the source Single, returns an
* Observable
* @return the Observable returned from {@code func} when applied to the item emitted by the source Single
* @see ReactiveX operators documentation: FlatMap
*/
public final Observable flatMapObservable(Func1 super T, ? extends Observable extends R>> func) {
return Observable.merge(asObservable(map(func)));
}
/**
* Returns a {@link Completable} that completes based on applying a specified function to the item emitted by the
* source {@link Completable}, where that function returns a {@link Completable}.
*
*
*
* - Scheduler:
* - {@code flatMapCompletable} does not operate by default on a particular {@link Scheduler}.
*
*
* @param func
* a function that, when applied to the item emitted by the source Single, returns a
* Completable
* @return the Completable returned from {@code func} when applied to the item emitted by the source Single
* @see ReactiveX operators documentation: FlatMap
* @since 1.3
*/
public final Completable flatMapCompletable(final Func1 super T, ? extends Completable> func) {
return Completable.create(new CompletableFlatMapSingleToCompletable(this, func));
}
/**
* Returns a Single that applies a specified function to the item emitted by the source Single and
* emits the result of this function application.
*
*
*
* - Scheduler:
* - {@code map} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the result value type
* @param func
* a function to apply to the item emitted by the Single
* @return a Single that emits the item from the source Single, transformed by the specified function
* @see ReactiveX operators documentation: Map
*/
public final Single map(Func1 super T, ? extends R> func) {
return create(new SingleOnSubscribeMap(this, func));
}
/**
* Flattens this and another Single into a single Observable, without any transformation.
*
*
*
* You can combine items emitted by multiple Singles so that they appear as a single Observable, by using
* the {@code mergeWith} method.
*
* - Scheduler:
* - {@code mergeWith} does not operate by default on a particular {@link Scheduler}.
*
*
* @param t1
* a Single to be merged
* @return an Observable that emits all of the items emitted by the source Singles
* @see ReactiveX operators documentation: Merge
*/
public final Observable mergeWith(Single extends T> t1) {
return merge(this, t1);
}
/**
* Modifies a Single to emit its item (or notify of its error) on a specified {@link Scheduler},
* asynchronously.
*
*
*
* - Scheduler:
* - you specify which {@link Scheduler} this operator will use
*
*
* @param scheduler
* the {@link Scheduler} to notify subscribers on
* @return the source Single modified so that its subscribers are notified on the specified
* {@link Scheduler}
* @see ReactiveX operators documentation: ObserveOn
* @see RxJava Threading Examples
* @see #subscribeOn
*/
public final Single observeOn(Scheduler scheduler) {
if (this instanceof ScalarSynchronousSingle) {
return ((ScalarSynchronousSingle)this).scalarScheduleOn(scheduler);
}
if (scheduler == null) {
throw new NullPointerException("scheduler is null");
}
return create(new SingleObserveOn(onSubscribe, scheduler));
}
/**
* Instructs a Single to emit an item (returned by a specified function) rather than invoking
* {@link SingleSubscriber#onError onError} if it encounters an error.
*
*
*
* By default, when a Single encounters an error that prevents it from emitting the expected item to its
* subscriber, the Single invokes its subscriber's {@link Subscriber#onError} method, and then quits
* without invoking any more of its subscriber's methods. The {@code onErrorReturn} method changes this
* behavior. If you pass a function ({@code resumeFunction}) to a Single's {@code onErrorReturn} method, if
* the original Single encounters an error, instead of invoking its subscriber's
* {@link Subscriber#onError} method, it will instead emit the return value of {@code resumeFunction}.
*
* You can use this to prevent errors from propagating or to supply fallback data should errors be
* encountered.
*
* - Scheduler:
* - {@code onErrorReturn} does not operate by default on a particular {@link Scheduler}.
*
*
* @param resumeFunction
* a function that returns an item that the new Single will emit if the source Single encounters
* an error
* @return the original Single with appropriately modified behavior
* @see ReactiveX operators documentation: Catch
*/
public final Single onErrorReturn(Func1 resumeFunction) {
return create(new SingleOnErrorReturn(onSubscribe, resumeFunction));
}
/**
* Instructs a Single to pass control to another Single rather than invoking
* {@link Observer#onError(Throwable)} if it encounters an error.
*
*
*
* By default, when a Single encounters an error that prevents it from emitting the expected item to
* its {@link Observer}, the Single invokes its Observer's {@code onError} method, and then quits
* without invoking any more of its Observer's methods. The {@code onErrorResumeNext} method changes this
* behavior. If you pass another Single ({@code resumeSingleInCaseOfError}) to a Single's
* {@code onErrorResumeNext} method, if the original Single encounters an error, instead of invoking its
* Observer's {@code onError} method, it will instead relinquish control to {@code resumeSingleInCaseOfError} which
* will invoke the Observer's {@link Observer#onNext onNext} method if it is able to do so. In such a case,
* because no Single necessarily invokes {@code onError}, the Observer may never know that an error
* happened.
*
* You can use this to prevent errors from propagating or to supply fallback data should errors be
* encountered.
*
* - Scheduler:
* - {@code onErrorResumeNext} does not operate by default on a particular {@link Scheduler}.
*
*
* @param resumeSingleInCaseOfError a Single that will take control if source Single encounters an error.
* @return the original Single, with appropriately modified behavior.
* @see ReactiveX operators documentation: Catch
* @since 1.3
*/
public final Single onErrorResumeNext(Single extends T> resumeSingleInCaseOfError) {
return new Single(SingleOperatorOnErrorResumeNext.withOther(this, resumeSingleInCaseOfError));
}
/**
* Instructs a Single to pass control to another Single rather than invoking
* {@link Observer#onError(Throwable)} if it encounters an error.
*
*
*
* By default, when a Single encounters an error that prevents it from emitting the expected item to
* its {@link Observer}, the Single invokes its Observer's {@code onError} method, and then quits
* without invoking any more of its Observer's methods. The {@code onErrorResumeNext} method changes this
* behavior. If you pass a function that will return another Single ({@code resumeFunctionInCaseOfError}) to a Single's
* {@code onErrorResumeNext} method, if the original Single encounters an error, instead of invoking its
* Observer's {@code onError} method, it will instead relinquish control to {@code resumeSingleInCaseOfError} which
* will invoke the Observer's {@link Observer#onNext onNext} method if it is able to do so. In such a case,
* because no Single necessarily invokes {@code onError}, the Observer may never know that an error
* happened.
*
* You can use this to prevent errors from propagating or to supply fallback data should errors be
* encountered.
*
* - Scheduler:
* - {@code onErrorResumeNext} does not operate by default on a particular {@link Scheduler}.
*
*
* @param resumeFunctionInCaseOfError a function that returns a Single that will take control if source Single encounters an error.
* @return the original Single, with appropriately modified behavior.
* @see ReactiveX operators documentation: Catch
* @since 1.3
*/
public final Single onErrorResumeNext(final Func1> resumeFunctionInCaseOfError) {
return new Single(SingleOperatorOnErrorResumeNext.withFunction(this, resumeFunctionInCaseOfError));
}
/**
* Subscribes to a Single but ignore its emission or notification.
*
* - Scheduler:
* - {@code subscribe} does not operate by default on a particular {@link Scheduler}.
*
*
* @return a {@link Subscription} reference can request the {@link Single} stop work.
* @throws OnErrorNotImplementedException
* if the Single tries to call {@link Subscriber#onError}
* @see ReactiveX operators documentation: Subscribe
*/
public final Subscription subscribe() {
return subscribe(Actions.empty(), Actions.errorNotImplemented());
}
/**
* Subscribes to a Single and provides a callback to handle the item it emits.
*
* - Scheduler:
* - {@code subscribe} does not operate by default on a particular {@link Scheduler}.
*
*
* @param onSuccess
* the {@code Action1} you have designed to accept the emission from the Single
* @return a {@link Subscription} reference can request the {@link Single} stop work.
* @throws IllegalArgumentException
* if {@code onNext} is null
* @throws OnErrorNotImplementedException
* if the Single tries to call {@link Subscriber#onError}
* @see ReactiveX operators documentation: Subscribe
*/
public final Subscription subscribe(final Action1 super T> onSuccess) {
return subscribe(onSuccess, Actions.errorNotImplemented());
}
/**
* Subscribes to a Single and provides callbacks to handle the item it emits or any error notification it
* issues.
*
* - Scheduler:
* - {@code subscribe} does not operate by default on a particular {@link Scheduler}.
*
*
* @param onSuccess
* the {@code Action1} you have designed to accept the emission from the Single
* @param onError
* the {@code Action1} you have designed to accept any error notification from the
* Single
* @return a {@link Subscription} reference can request the {@link Single} stop work.
* @see ReactiveX operators documentation: Subscribe
* @throws IllegalArgumentException
* if {@code onNext} is null, or
* if {@code onError} is null
*/
public final Subscription subscribe(final Action1 super T> onSuccess, final Action1 onError) {
if (onSuccess == null) {
throw new IllegalArgumentException("onSuccess can not be null");
}
if (onError == null) {
throw new IllegalArgumentException("onError can not be null");
}
return subscribe(new SingleSubscriber() {
@Override
public final void onError(Throwable e) {
try {
onError.call(e);
} finally {
unsubscribe();
}
}
@Override
public final void onSuccess(T args) {
try {
onSuccess.call(args);
} finally {
unsubscribe();
}
}
});
}
/**
* Subscribes to a Single and invokes the {@link OnSubscribe} function without any contract protection,
* error handling, unsubscribe, or execution hooks.
*
* Use this only for implementing an {@link Operator} that requires nested subscriptions. For other
* purposes, use {@link #subscribe(Subscriber)} which ensures the Rx contract and other functionality.
*
*