All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rx.Single Maven / Gradle / Ivy

There is a newer version: 1.3.8
Show newest version
/**
 * 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.operators.*;
import rx.internal.producers.SingleDelayedProducer;
import rx.internal.util.*;
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 (If this class graduates from "Experimental" replace this parenthetical with the release number) */ @Beta public class Single { final Observable.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 OnExecute} to be executed when {@code execute(SingleSubscriber)} or * {@code subscribe(Subscriber)} is called */ protected Single(OnSubscribe f) { final OnSubscribe g = RxJavaHooks.onCreate(f); // bridge between OnSubscribe (which all Operators and Observables use) and OnExecute (for Single) this.onSubscribe = new Observable.OnSubscribe() { @Override public void call(final Subscriber child) { final SingleDelayedProducer producer = new SingleDelayedProducer(child); child.setProducer(producer); SingleSubscriber ss = new SingleSubscriber() { @Override public void onSuccess(T value) { producer.setValue(value); } @Override public void onError(Throwable error) { child.onError(error); } }; child.add(ss); g.call(ss); } }; } private Single(final Observable.OnSubscribe f) { this.onSubscribe = RxJavaHooks.onCreate(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 */ @Experimental public final Single lift(final Operator lift) { return new Single(new Observable.OnSubscribe() { @Override public void call(Subscriber o) { try { final Subscriber st = RxJavaHooks.onSingleLift(lift).call(o); try { // new Subscriber created and being subscribed with so 'onStart' it st.onStart(); onSubscribe.call(st); } catch (Throwable e) { // localized capture of errors rather than it skipping all operators // and ending up in the try/catch of the subscribe method which then // prevents onErrorResumeNext and other similar approaches to error handling Exceptions.throwOrReport(e, st); } } catch (Throwable e) { // if the lift function failed all we can do is pass the error to the final Subscriber // as we don't have the operator available to us Exceptions.throwOrReport(e, o); } } }); } /** * 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 transformer) { return ((Transformer) transformer).call(this); } /** * Transformer function used by {@link #compose}. * * @warn more complete description needed * @param the source Single's value type * @param the transformed Single's value type */ public interface Transformer extends Func1, Single> { // cover for generics insanity } /** * * * @warn more complete description needed */ private static Observable asObservable(Single t) { // is this sufficient, or do I need to keep the outer Single and subscribe to it? return Observable.create(t.onSubscribe); } /** * INTERNAL: Used with lift and operators. * * Converts the source {@code Single} into an {@code Single>} that emits an Observable * that emits the same emission as the source Single. *

* *

*
Scheduler:
*
{@code nest} does not operate by default on a particular {@link Scheduler}.
*
* * @return a Single that emits an Observable that emits the same item as the source Single * @see ReactiveX operators documentation: To */ @SuppressWarnings("unused") private Single> nest() { return Single.just(asObservable(this)); } /* ********************************************************************************************************* * Operators Below Here * ********************************************************************************************************* */ /** * 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 t1, Single 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 t1, Single t2, Single 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 t1, Single t2, Single t3, Single 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 t1, Single t2, Single t3, Single t4, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single t6, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single t6, Single t7, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single t6, Single t7, Single t8, Single 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 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 */ @SuppressWarnings("cast") public static Single from(Future future) { return new Single((Observable.OnSubscribe)OnSubscribeToObservableFuture.toObservableFuture(future)); } /** * 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 */ @SuppressWarnings("cast") public static Single from(Future future, long timeout, TimeUnit unit) { return new Single((Observable.OnSubscribe)OnSubscribeToObservableFuture.toObservableFuture(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 */ @SuppressWarnings("cast") public static Single from(Future future, Scheduler scheduler) { return new Single((Observable.OnSubscribe)OnSubscribeToObservableFuture.toObservableFuture(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. */ @Beta public static Single fromCallable(final Callable func) { return create(new OnSubscribe() { @Override public void call(SingleSubscriber singleSubscriber) { T value; try { value = func.call(); } catch (Throwable t) { Exceptions.throwIfFatal(t); singleSubscriber.onError(t); return; } singleSubscriber.onSuccess(value); } }); } /** * 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> source) { if (source instanceof ScalarSynchronousSingle) { return ((ScalarSynchronousSingle) source).scalarFlatMap((Func1) UtilityFunctions.identity()); } return Single.create(new OnSubscribe() { @Override public void call(final SingleSubscriber child) { SingleSubscriber> parent = new SingleSubscriber>() { @Override public void onSuccess(Single 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 t1, Single 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 t1, Single t2, Single 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 t1, Single t2, Single t3, Single 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 t1, Single t2, Single t3, Single t4, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single t6, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single t6, Single t7, Single 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 t1, Single t2, Single t3, Single t4, Single t5, Single t6, Single t7, Single t8, Single t9) { return Observable.merge(asObservable(t1), asObservable(t2), asObservable(t3), asObservable(t4), asObservable(t5), asObservable(t6), asObservable(t7), asObservable(t8), asObservable(t9)); } /** * 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 s1, Single s2, final Func2 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 s1, Single s2, Single s3, final Func3 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 s1, Single s2, Single s3, Single s4, final Func4 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 s1, Single s2, Single s3, Single s4, Single s5, final Func5 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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, final Func6 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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7, final Func7 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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7, Single s8, final Func8 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 s1, Single s2, Single s3, Single s4, Single s5, Single s6, Single s7, Single s8, Single s9, final Func9 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> singles, FuncN zipFunction) { @SuppressWarnings("rawtypes") Single[] iterableToArray = iterableToArray(singles); return SingleOperatorZip.zip(iterableToArray, zipFunction); } /** * 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 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> 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> 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 * @Experimental The behavior of this can change at any time. * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the release number) */ @Experimental public final Completable flatMapCompletable(final Func1 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 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 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); } // Note that since Single emits onSuccess xor onError, // there is no cut-ahead possible like with regular Observable sequences. return lift(new OperatorObserveOn(scheduler, false)); } /** * 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 */ @SuppressWarnings("cast") public final Single onErrorReturn(Func1 resumeFunction) { return lift((Operator)OperatorOnErrorResumeNextViaFunction.withSingle(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 * @Experimental The behavior of this can change at any time. * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the release number) */ @Experimental public final Single onErrorResumeNext(Single 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 * @Experimental The behavior of this can change at any time. * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the release number) */ @Experimental 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(new Subscriber() { @Override public final void onCompleted() { // do nothing } @Override public final void onError(Throwable e) { throw new OnErrorNotImplementedException(e); } @Override public final void onNext(T args) { // do nothing } }); } /** * 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 onSuccess) { if (onSuccess == null) { throw new IllegalArgumentException("onSuccess can not be null"); } return subscribe(new Subscriber() { @Override public final void onCompleted() { // do nothing } @Override public final void onError(Throwable e) { throw new OnErrorNotImplementedException(e); } @Override public final void onNext(T args) { onSuccess.call(args); } }); } /** * 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 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 Subscriber() { @Override public final void onCompleted() { // do nothing } @Override public final void onError(Throwable e) { onError.call(e); } @Override public final void onNext(T args) { onSuccess.call(args); } }); } /** * 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. *

*
Scheduler:
*
{@code unsafeSubscribe} does not operate by default on a particular {@link Scheduler}.
*
* * @param subscriber * the Subscriber that will handle the emission or notification from the Single * @return the subscription that allows unsubscribing */ public final Subscription unsafeSubscribe(Subscriber subscriber) { try { // new Subscriber so onStart it subscriber.onStart(); RxJavaHooks.onSingleStart(this, onSubscribe).call(subscriber); return RxJavaHooks.onSingleReturn(subscriber); } catch (Throwable e) { // special handling for certain Throwable/Error/Exception types Exceptions.throwIfFatal(e); // if an unhandled error occurs executing the onSubscribe we will propagate it try { subscriber.onError(RxJavaHooks.onSingleError(e)); } catch (Throwable e2) { Exceptions.throwIfFatal(e2); // if this happens it means the onError itself failed (perhaps an invalid function implementation) // so we are unable to propagate the error correctly and will just throw RuntimeException r = new RuntimeException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2); // TODO could the hook be the cause of the error in the on error handling. RxJavaHooks.onSingleError(r); // TODO why aren't we throwing the hook's return value. throw r; // NOPMD } return Subscriptions.unsubscribed(); } } /** * Subscribes an Observer to this single and returns a Subscription that allows * unsubscription. * * @param observer the Observer to subscribe * @return the Subscription that allows unsubscription */ public final Subscription subscribe(final Observer observer) { if (observer == null) { throw new NullPointerException("observer is null"); } return subscribe(new SingleSubscriber() { @Override public void onSuccess(T value) { observer.onNext(value); observer.onCompleted(); } @Override public void onError(Throwable error) { observer.onError(error); } }); } /** * Subscribes to a Single and provides a Subscriber that implements functions to handle the item the Single * emits or any error notification it issues. *

* A typical implementation of {@code subscribe} does the following: *

    *
  1. It stores a reference to the Subscriber in a collection object, such as a {@code List} object.
  2. *
  3. It returns a reference to the {@link Subscription} interface. This enables Subscribers to * unsubscribe, that is, to stop receiving the item or notification before the Single completes.
  4. *

* A {@code Single} instance is responsible for accepting all subscriptions and notifying all * Subscribers. Unless the documentation for a particular {@code Single} implementation indicates * otherwise, Subscribers should make no assumptions about the order in which multiple Subscribers will * receive their notifications. *

* For more information see the * ReactiveX documentation. *

*
Scheduler:
*
{@code subscribe} does not operate by default on a particular {@link Scheduler}.
*
* * @param subscriber * the {@link Subscriber} that will handle the emission or notification from the Single * @return a {@link Subscription} reference can request the {@link Single} stop work. * @throws IllegalStateException * if {@code subscribe} is unable to obtain an {@code OnSubscribe<>} function * @throws IllegalArgumentException * if the {@link Subscriber} provided as the argument to {@code subscribe} is {@code null} * @throws OnErrorNotImplementedException * if the {@link Subscriber}'s {@code onError} method is null * @throws RuntimeException * if the {@link Subscriber}'s {@code onError} method itself threw a {@code Throwable} * @see ReactiveX operators documentation: Subscribe */ public final Subscription subscribe(Subscriber subscriber) { // validate and proceed if (subscriber == null) { throw new IllegalArgumentException("observer can not be null"); } if (onSubscribe == null) { throw new IllegalStateException("onSubscribe function can not be null."); /* * the subscribe function can also be overridden but generally that's not the appropriate approach * so I won't mention that in the exception */ } // new Subscriber so onStart it subscriber.onStart(); /* * See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls * to user code from within an Observer" */ // if not already wrapped if (!(subscriber instanceof SafeSubscriber)) { // assign to `observer` so we return the protected version subscriber = new SafeSubscriber(subscriber); } // The code below is exactly the same an unsafeSubscribe but not used because it would add a significant depth to already huge call stacks. try { // allow the hook to intercept and/or decorate RxJavaHooks.onSingleStart(this, onSubscribe).call(subscriber); return RxJavaHooks.onSingleReturn(subscriber); } catch (Throwable e) { // special handling for certain Throwable/Error/Exception types Exceptions.throwIfFatal(e); // if an unhandled error occurs executing the onSubscribe we will propagate it try { subscriber.onError(RxJavaHooks.onSingleError(e)); } catch (Throwable e2) { Exceptions.throwIfFatal(e2); // if this happens it means the onError itself failed (perhaps an invalid function implementation) // so we are unable to propagate the error correctly and will just throw RuntimeException r = new RuntimeException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2); // TODO could the hook be the cause of the error in the on error handling. RxJavaHooks.onSingleError(r); // TODO why aren't we throwing the hook's return value. throw r; // NOPMD } return Subscriptions.empty(); } } /** * Subscribes to a Single and provides a {@link SingleSubscriber} that implements functions to handle the * item the Single emits or any error notification it issues. *

* A typical implementation of {@code subscribe} does the following: *

    *
  1. It stores a reference to the Subscriber in a collection object, such as a {@code List} object.
  2. *
  3. It returns a reference to the {@link Subscription} interface. This enables Subscribers to * unsubscribe, that is, to stop receiving the item or notification before the Single completes.
  4. *

* A {@code Single} instance is responsible for accepting all subscriptions and notifying all * Subscribers. Unless the documentation for a particular {@code Single} implementation indicates * otherwise, Subscribers should make no assumptions about the order in which multiple Subscribers will * receive their notifications. *

* For more information see the * ReactiveX documentation. *

*
Scheduler:
*
{@code subscribe} does not operate by default on a particular {@link Scheduler}.
*
* * @param te * the {@link SingleSubscriber} that will handle the emission or notification from the Single * @return a {@link Subscription} reference can request the {@link Single} stop work. * @throws IllegalStateException * if {@code subscribe} is unable to obtain an {@code OnSubscribe<>} function * @throws IllegalArgumentException * if the {@link SingleSubscriber} provided as the argument to {@code subscribe} is {@code null} * @throws OnErrorNotImplementedException * if the {@link SingleSubscriber}'s {@code onError} method is null * @throws RuntimeException * if the {@link SingleSubscriber}'s {@code onError} method itself threw a {@code Throwable} * @see ReactiveX operators documentation: Subscribe */ public final Subscription subscribe(final SingleSubscriber te) { Subscriber s = new Subscriber() { @Override public void onCompleted() { // deliberately ignored } @Override public void onError(Throwable e) { te.onError(e); } @Override public void onNext(T t) { te.onSuccess(t); } }; te.add(s); subscribe(s); return s; } /** * Asynchronously subscribes subscribers to this Single on the specified {@link Scheduler}. *

* *

*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
* * @param scheduler * the {@link Scheduler} to perform subscription actions on * @return the source Single modified so that its subscriptions happen on the specified {@link Scheduler} * @see ReactiveX operators documentation: SubscribeOn * @see RxJava Threading Examples * @see #observeOn */ public final Single subscribeOn(final Scheduler scheduler) { if (this instanceof ScalarSynchronousSingle) { return ((ScalarSynchronousSingle)this).scalarScheduleOn(scheduler); } return create(new OnSubscribe() { @Override public void call(final SingleSubscriber t) { final Scheduler.Worker w = scheduler.createWorker(); t.add(w); w.schedule(new Action0() { @Override public void call() { SingleSubscriber ssub = new SingleSubscriber() { @Override public void onSuccess(T value) { try { t.onSuccess(value); } finally { w.unsubscribe(); } } @Override public void onError(Throwable error) { try { t.onError(error); } finally { w.unsubscribe(); } } }; t.add(ssub); Single.this.subscribe(ssub); } }); } }); } /** * Returns a Single that emits the item emitted by the source Single until a Completable terminates. Upon * termination of {@code other}, this will emit a {@link CancellationException} rather than go to * {@link SingleSubscriber#onSuccess(Object)}. *

* *

*
Scheduler:
*
{@code takeUntil} does not operate by default on a particular {@link Scheduler}.
*
* * @param other * the Completable whose termination will cause {@code takeUntil} to emit the item from the source * Single * @return a Single that emits the item emitted by the source Single until such time as {@code other} terminates. * @see ReactiveX operators documentation: TakeUntil */ public final Single takeUntil(final Completable other) { return lift(new Operator() { @Override public Subscriber call(Subscriber child) { final Subscriber serial = new SerializedSubscriber(child, false); final Subscriber main = new Subscriber(serial, false) { @Override public void onNext(T t) { serial.onNext(t); } @Override public void onError(Throwable e) { try { serial.onError(e); } finally { serial.unsubscribe(); } } @Override public void onCompleted() { try { serial.onCompleted(); } finally { serial.unsubscribe(); } } }; final CompletableSubscriber so = new CompletableSubscriber() { @Override public void onCompleted() { onError(new CancellationException("Stream was canceled before emitting a terminal event.")); } @Override public void onError(Throwable e) { main.onError(e); } @Override public void onSubscribe(Subscription d) { serial.add(d); } }; serial.add(main); child.add(serial); other.unsafeSubscribe(so); return main; } }); } /** * Returns a Single that emits the item emitted by the source Single until an Observable emits an item. Upon * emission of an item from {@code other}, this will emit a {@link CancellationException} rather than go to * {@link SingleSubscriber#onSuccess(Object)}. *

* *

*
Scheduler:
*
{@code takeUntil} does not operate by default on a particular {@link Scheduler}.
*
* * @param other * the Observable whose first emitted item will cause {@code takeUntil} to emit the item from the source * Single * @param * the type of items emitted by {@code other} * @return a Single that emits the item emitted by the source Single until such time as {@code other} emits * its first item * @see ReactiveX operators documentation: TakeUntil */ public final Single takeUntil(final Observable other) { return lift(new Operator() { @Override public Subscriber call(Subscriber child) { final Subscriber serial = new SerializedSubscriber(child, false); final Subscriber main = new Subscriber(serial, false) { @Override public void onNext(T t) { serial.onNext(t); } @Override public void onError(Throwable e) { try { serial.onError(e); } finally { serial.unsubscribe(); } } @Override public void onCompleted() { try { serial.onCompleted(); } finally { serial.unsubscribe(); } } }; final Subscriber so = new Subscriber() { @Override public void onCompleted() { onError(new CancellationException("Stream was canceled before emitting a terminal event.")); } @Override public void onError(Throwable e) { main.onError(e); } @Override public void onNext(E e) { onError(new CancellationException("Stream was canceled before emitting a terminal event.")); } }; serial.add(main); serial.add(so); child.add(serial); other.unsafeSubscribe(so); return main; } }); } /** * Returns a Single that emits the item emitted by the source Single until a second Single emits an item. Upon * emission of an item from {@code other}, this will emit a {@link CancellationException} rather than go to * {@link SingleSubscriber#onSuccess(Object)}. *

* *

*
Scheduler:
*
{@code takeUntil} does not operate by default on a particular {@link Scheduler}.
*
* * @param other * the Single whose emitted item will cause {@code takeUntil} to emit the item from the source Single * @param * the type of item emitted by {@code other} * @return a Single that emits the item emitted by the source Single until such time as {@code other} emits its item * @see ReactiveX operators documentation: TakeUntil */ public final Single takeUntil(final Single other) { return lift(new Operator() { @Override public Subscriber call(Subscriber child) { final Subscriber serial = new SerializedSubscriber(child, false); final Subscriber main = new Subscriber(serial, false) { @Override public void onNext(T t) { serial.onNext(t); } @Override public void onError(Throwable e) { try { serial.onError(e); } finally { serial.unsubscribe(); } } @Override public void onCompleted() { try { serial.onCompleted(); } finally { serial.unsubscribe(); } } }; final SingleSubscriber so = new SingleSubscriber() { @Override public void onSuccess(E value) { onError(new CancellationException("Stream was canceled before emitting a terminal event.")); } @Override public void onError(Throwable e) { main.onError(e); } }; serial.add(main); serial.add(so); child.add(serial); other.subscribe(so); return main; } }); } /** * Calls the specified converter function during assembly time and returns its resulting value. *

* This allows fluent conversion to any other type. * @param the resulting object type * @param converter the function that receives the current Single instance and returns a value * @return the value returned by the function */ @Experimental public final R to(Func1, R> converter) { return converter.call(this); } /** * Converts this Single into an {@link Observable}. *

* * * @return an {@link Observable} that emits a single item T. */ public final Observable toObservable() { return asObservable(this); } /** * Returns a {@link Completable} that discards result of the {@link Single} (similar to * {@link Observable#ignoreElements()}) and calls {@code onCompleted} when this source {@link Single} calls * {@code onSuccess}. Error terminal event is propagated. *

* *

*
Scheduler:
*
{@code toCompletable} does not operate by default on a particular {@link Scheduler}.
*
* * @return a {@link Completable} that calls {@code onCompleted} on it's subscriber when the source {@link Single} * calls {@code onSuccess}. * @see ReactiveX documentation: Completable * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical * with the release number). */ @Experimental public final Completable toCompletable() { return Completable.fromSingle(this); } /** * Returns a Single that mirrors the source Single but applies a timeout policy for its emitted item. If it * is not emitted within the specified timeout duration, the resulting Single terminates and notifies * subscribers of a {@code TimeoutException}. *

* *

*
Scheduler:
*
This version of {@code timeout} operates by default on the {@code computation} {@link Scheduler}.
*
* * @param timeout * maximum duration before the Single times out * @param timeUnit * the unit of time that applies to the {@code timeout} argument. * @return the source Single modified to notify subscribers of a {@code TimeoutException} in case of a * timeout * @see ReactiveX operators documentation: Timeout */ public final Single timeout(long timeout, TimeUnit timeUnit) { return timeout(timeout, timeUnit, null, Schedulers.computation()); } /** * Returns a Single that mirrors the source Single but applies a timeout policy for its emitted item, where * this policy is governed on a specified Scheduler. If the item is not emitted within the specified timeout * duration, the resulting Single terminates and notifies subscribers of a {@code TimeoutException}. *

* *

*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
* * @param timeout * maximum duration before the Single times out * @param timeUnit * the unit of time that applies to the {@code timeout} argument * @param scheduler * the Scheduler to run the timeout timers on * @return the source Single modified to notify subscribers of a {@code TimeoutException} in case of a * timeout * @see ReactiveX operators documentation: Timeout */ public final Single timeout(long timeout, TimeUnit timeUnit, Scheduler scheduler) { return timeout(timeout, timeUnit, null, scheduler); } /** * Returns a Single that mirrors the source Single but applies a timeout policy for its emitted item. If it * is not emitted within the specified timeout duration, the resulting Single instead mirrors a fallback * Single. *

* *

*
Scheduler:
*
This version of {@code timeout} operates by default on the {@code computation} {@link Scheduler}.
*
* * @param timeout * maximum time before a timeout occurs * @param timeUnit * the unit of time that applies to the {@code timeout} argument * @param other * the fallback Single to use in case of a timeout * @return the source Single modified to switch to the fallback Single in case of a timeout * @see ReactiveX operators documentation: Timeout */ public final Single timeout(long timeout, TimeUnit timeUnit, Single other) { return timeout(timeout, timeUnit, other, Schedulers.computation()); } /** * Returns a Single that mirrors the source Single but applies a timeout policy for its emitted item, using * a specified Scheduler. If the item isn't emitted within the specified timeout duration, the resulting * Single instead mirrors a fallback Single. *

* *

*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
* * @param timeout * maximum duration before a timeout occurs * @param timeUnit * the unit of time that applies to the {@code timeout} argument * @param other * the Single to use as the fallback in case of a timeout * @param scheduler * the {@link Scheduler} to run the timeout timers on * @return the source Single modified so that it will switch to the fallback Single in case of a timeout * @see ReactiveX operators documentation: Timeout */ public final Single timeout(long timeout, TimeUnit timeUnit, Single other, Scheduler scheduler) { if (other == null) { other = Single. error(new TimeoutException()); } return lift(new OperatorTimeout(timeout, timeUnit, asObservable(other), scheduler)); } /** * Converts a Single into a {@link BlockingSingle} (a Single with blocking operators). *
*
Scheduler:
*
{@code toBlocking} does not operate by default on a particular {@link Scheduler}.
*
* * @return a {@code BlockingSingle} version of this Single. * @see ReactiveX operators documentation: To */ @Experimental public final BlockingSingle toBlocking() { return BlockingSingle.from(this); } /** * Returns a Single that emits the result of applying a specified function to the pair of items emitted by * the source Single and another specified Single. *

* *

*
Scheduler:
*
{@code zipWith} does not operate by default on a particular {@link Scheduler}.
*
* * @param * the type of items emitted by the {@code other} Single * @param * the type of items emitted by the resulting Single * @param other * the other Observable * @param zipFunction * a function that combines the pairs of items from the two Observables to generate the items to * be emitted by the resulting Single * @return an Observable that pairs up values from the source Observable and the {@code other} Observable * and emits the results of {@code zipFunction} applied to these pairs * @see ReactiveX operators documentation: Zip */ @SuppressWarnings("cast") public final Single zipWith(Single other, Func2 zipFunction) { return (Single)zip(this, other, zipFunction); } /** * Modifies the source {@link Single} so that it invokes an action if it calls {@code onError}. *

* In case the onError action throws, the downstream will receive a composite exception containing * the original exception and the exception thrown by onError. *

* *

*
Scheduler:
*
{@code doOnError} does not operate by default on a particular {@link Scheduler}.
*
* * @param onError * the action to invoke if the source {@link Single} calls {@code onError} * @return the source {@link Single} with the side-effecting behavior applied * @see ReactiveX operators documentation: Do * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the release number) */ @Experimental public final Single doOnError(final Action1 onError) { if (onError == null) { throw new IllegalArgumentException("onError is null"); } return Single.create(new SingleDoOnEvent(this, Actions.empty(), new Action1() { @Override public void call(final Throwable throwable) { onError.call(throwable); } })); } /** * Modifies the source {@link Single} so that it invokes an action when it calls {@code onSuccess} or {@code onError}. *

* *

*
Scheduler:
*
{@code doOnEach} does not operate by default on a particular {@link Scheduler}.
*
* * @param onNotification * the action to invoke when the source {@link Single} calls {@code onSuccess} or {@code onError}. * @return the source {@link Single} with the side-effecting behavior applied * @see ReactiveX operators documentation: Do * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the release number) */ @Experimental public final Single doOnEach(final Action1> onNotification) { if (onNotification == null) { throw new IllegalArgumentException("onNotification is null"); } return Single.create(new SingleDoOnEvent(this, new Action1() { @Override public void call(final T t) { onNotification.call(Notification.createOnNext(t)); } }, new Action1() { @Override public void call(final Throwable throwable) { onNotification.call(Notification.createOnError(throwable)); } })); } /** * Modifies the source {@link Single} so that it invokes an action when it calls {@code onSuccess}. *

* *

*
Scheduler:
*
{@code doOnSuccess} does not operate by default on a particular {@link Scheduler}.
*
* * @param onSuccess * the action to invoke when the source {@link Single} calls {@code onSuccess} * @return the source {@link Single} with the side-effecting behavior applied * @see ReactiveX operators documentation: Do * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the release number) */ @Experimental public final Single doOnSuccess(final Action1 onSuccess) { if (onSuccess == null) { throw new IllegalArgumentException("onSuccess is null"); } return Single.create(new SingleDoOnEvent(this, new Action1() { @Override public void call(final T t) { onSuccess.call(t); } }, new Action1() { @Override public void call(final Throwable throwable) { // Do nothing. } })); } /** * Modifies the source {@code Single} so that it invokes the given action when it is subscribed from * its subscribers. Each subscription will result in an invocation of the given action except when the * source {@code Single} is reference counted, in which case the source {@code Single} will invoke * the given action for the first subscription. *

* *

*
Scheduler:
*
{@code doOnSubscribe} does not operate by default on a particular {@link Scheduler}.
*
* * @param subscribe * the action that gets called when an observer subscribes to this {@code Single} * @return the source {@code Single} modified so as to call this Action when appropriate * @see ReactiveX operators documentation: Do */ @Experimental public final Single doOnSubscribe(final Action0 subscribe) { return lift(new OperatorDoOnSubscribe(subscribe)); } /** * Returns a Single that emits the items emitted by the source Single shifted forward in time by a * specified delay. Error notifications from the source Single are not delayed. *

* *

*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
* * @param delay * the delay to shift the source by * @param unit * the time unit of {@code delay} * @param scheduler * the {@link Scheduler} to use for delaying * @return the source Single shifted in time by the specified delay * @see ReactiveX operators documentation: Delay */ @Experimental public final Single delay(long delay, TimeUnit unit, Scheduler scheduler) { return lift(new OperatorDelay(delay, unit, scheduler)); } /** * Returns a Single that emits the items emitted by the source Single shifted forward in time by a * specified delay. Error notifications from the source Observable are not delayed. *

* *

*
Scheduler:
*
This version of {@code delay} operates by default on the {@code computation} {@link Scheduler}.
*
* * @param delay * the delay to shift the source by * @param unit * the {@link TimeUnit} in which {@code period} is defined * @return the source Single shifted in time by the specified delay * @see ReactiveX operators documentation: Delay */ @Experimental public final Single delay(long delay, TimeUnit unit) { return delay(delay, unit, Schedulers.computation()); } /** * Returns a {@link Single} that calls a {@link Single} factory to create a {@link Single} for each new Observer * that subscribes. That is, for each subscriber, the actual {@link Single} that subscriber observes is * determined by the factory function. *

* *

* The defer Observer allows you to defer or delay emitting value from a {@link Single} until such time as an * Observer subscribes to the {@link Single}. This allows an {@link Observer} to easily obtain updates or a * refreshed version of the sequence. *

*
Scheduler:
*
{@code defer} does not operate by default on a particular {@link Scheduler}.
*
* * @param singleFactory * the {@link Single} factory function to invoke for each {@link Observer} that subscribes to the * resulting {@link Single}. * @param * the type of the items emitted by the {@link Single}. * @return a {@link Single} whose {@link Observer}s' subscriptions trigger an invocation of the given * {@link Single} factory function. * @see ReactiveX operators documentation: Defer */ @Experimental public static Single defer(final Callable> singleFactory) { return create(new OnSubscribe() { @Override public void call(SingleSubscriber singleSubscriber) { Single single; try { single = singleFactory.call(); } catch (Throwable t) { Exceptions.throwIfFatal(t); singleSubscriber.onError(t); return; } single.subscribe(singleSubscriber); } }); } /** * Modifies the source {@link Single} so that it invokes the given action when it is unsubscribed from * its subscribers. *

* *

*
Scheduler:
*
{@code doOnUnsubscribe} does not operate by default on a particular {@link Scheduler}.
*
* * @param action * the action that gets called when this {@link Single} is unsubscribed. * @return the source {@link Single} modified so as to call this Action when appropriate. * @see ReactiveX operators documentation: Do */ @Experimental public final Single doOnUnsubscribe(final Action0 action) { return lift(new OperatorDoOnUnsubscribe(action)); } /** * Registers an {@link Action0} to be called when this {@link Single} invokes either * {@link SingleSubscriber#onSuccess(Object)} onSuccess} or {@link SingleSubscriber#onError onError}. *

* *

*
Scheduler:
*
{@code doAfterTerminate} does not operate by default on a particular {@link Scheduler}.
*
* * @param action * an {@link Action0} to be invoked when the source {@link Single} finishes. * @return a {@link Single} that emits the same item or error as the source {@link Single}, then invokes the * {@link Action0} * @see ReactiveX operators documentation: Do */ @Experimental public final Single doAfterTerminate(Action0 action) { return create(new SingleDoAfterTerminate(this, action)); } /** * FOR INTERNAL USE ONLY. *

* Converts {@link Iterable} of {@link Single} to array of {@link Single}. * * @param singlesIterable * non null iterable of {@link Single}. * @return array of {@link Single} with same length as passed iterable. */ @SuppressWarnings("unchecked") static Single[] iterableToArray(final Iterable> singlesIterable) { Single[] singlesArray; int count; if (singlesIterable instanceof Collection) { Collection> list = (Collection>) singlesIterable; count = list.size(); singlesArray = list.toArray(new Single[count]); } else { Single[] tempArray = new Single[8]; // Magic number used just to reduce number of allocations. count = 0; for (Single s : singlesIterable) { if (count == tempArray.length) { Single[] sb = new Single[count + (count >> 2)]; System.arraycopy(tempArray, 0, sb, 0, count); tempArray = sb; } tempArray[count] = s; count++; } if (tempArray.length == count) { singlesArray = tempArray; } else { singlesArray = new Single[count]; System.arraycopy(tempArray, 0, singlesArray, 0, count); } } return singlesArray; } /** * Returns a Single that mirrors the source Single, resubscribing to it if it calls {@code onError} * (infinite retry count). * * * * If the source Single calls {@link SingleSubscriber#onError}, this method will resubscribe to the source * Single rather than propagating the {@code onError} call. * *

*
Scheduler:
*
{@code retry} operates by default on the {@code trampoline} {@link Scheduler}.
*
* * @return the source Single modified with retry logic * @see ReactiveX operators documentation: Retry */ public final Single retry() { return toObservable().retry().toSingle(); } /** * Returns a Single that mirrors the source Single, resubscribing to it if it calls {@code onError} * up to a specified number of retries. * * * * If the source Single calls {@link SingleSubscriber#onError}, this method will resubscribe to the source * Single for a maximum of {@code count} resubscriptions rather than propagating the * {@code onError} call. * *
*
Scheduler:
*
{@code retry} operates by default on the {@code trampoline} {@link Scheduler}.
*
* * @param count * number of retry attempts before failing * * @return the source Single modified with retry logic * @see ReactiveX operators documentation: Retry */ public final Single retry(final long count) { return toObservable().retry(count).toSingle(); } /** * Returns a Single that mirrors the source Single, resubscribing to it if it calls {@code onError} * and the predicate returns true for that specific exception and retry count. * * *
*
Backpressure Support:
*
This operator honors backpressure. *
Scheduler:
*
{@code retry} operates by default on the {@code trampoline} {@link Scheduler}.
*
* * @param predicate * the predicate that determines if a resubscription may happen in case of a specific exception * and retry count * * @return the source Single modified with retry logic * @see #retry() * @see ReactiveX operators documentation: Retry */ public final Single retry(Func2 predicate) { return toObservable().retry(predicate).toSingle(); } /** * Returns a Single that emits the same values as the source Single with the exception of an * {@code onError}. An {@code onError} notification from the source will result in the emission of a * {@link Throwable} item to the Observable provided as an argument to the {@code notificationHandler} * function. *

Emissions from the handler {@code Observable} is treated as follows: *

    *
  • If the handler {@code Observable} emits an {@code onCompleted} the {@code retryWhen} will call {@code onError} * with {@code NoSuchElementException} on the child subscription.
  • *
  • If the handler {@code Observable} emits an {@code onError} the {@code retryWhen} will call * {@code onError} with the same Throwable instance on the child subscription. *
  • Otherwise, the operator will resubscribe to the source Single.
  • *
*

The {@code notificationHandler} function is called for each subscriber individually. This allows per-Subscriber * state to be added to the error notification sequence.

*

     * single.retryWhen(error -> {
     *     AtomicInteger counter = new AtomicInteger();
     *     return error.takeWhile(e -> counter.incrementAndGet() < 3).map(e -> "retry");
     * }).subscribe(...);
     * 
*

* Note that you must compose over the input {@code Observable} provided in the function call because {@retryWhen} expects * an emission of the exception to be matched by an event from the handler Observable. *

* * * *

*
Scheduler:
*
{@code retryWhen} operates by default on the {@code trampoline} {@link Scheduler}.
*
* * @param notificationHandler * receives an Observable of notifications with which a user can complete or error, aborting the * retry * * @return the source Single modified with retry logic * @see ReactiveX operators documentation: Retry */ public final Single retryWhen(final Func1, ? extends Observable> notificationHandler) { return toObservable().retryWhen(notificationHandler).toSingle(); } /** * Constructs a Single that creates a dependent resource object which is disposed of on unsubscription. *

* *

*
Scheduler:
*
{@code using} does not operate by default on a particular {@link Scheduler}.
*
* * @param the value type of the generated source * @param the type of the per-subscriber resource * @param resourceFactory * the factory function to create a resource object that depends on the Single * @param singleFactory * the factory function to create a Single * @param disposeAction * the function that will dispose of the resource * @return the Single whose lifetime controls the lifetime of the dependent resource object * @see ReactiveX operators documentation: Using */ @Experimental public static Single using( final Func0 resourceFactory, final Func1> singleFactory, final Action1 disposeAction) { return using(resourceFactory, singleFactory, disposeAction, false); } /** * Constructs a Single that creates a dependent resource object which is disposed of just before * termination if you have set {@code disposeEagerly} to {@code true} and unsubscription does not occur * before termination. Otherwise resource disposal will occur on unsubscription. Eager disposal is * particularly appropriate for a synchronous Single that reuses resources. {@code disposeAction} will * only be called once per subscription. *

* *

*
Scheduler:
*
{@code using} does not operate by default on a particular {@link Scheduler}.
*
* * @param the value type of the generated source * @param the type of the per-subscriber resource * @param resourceFactory * the factory function to create a resource object that depends on the Single * @param singleFactory * the factory function to create a Single * @param disposeAction * the function that will dispose of the resource * @param disposeEagerly * if {@code true} then disposal will happen either on unsubscription or just before emission of * a terminal event ({@code onComplete} or {@code onError}). * @return the Single whose lifetime controls the lifetime of the dependent resource object * @see ReactiveX operators documentation: Using * @Experimental The behavior of this can change at any time. * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the release number) */ @Experimental public static Single using( final Func0 resourceFactory, final Func1> singleFactory, final Action1 disposeAction, boolean disposeEagerly) { if (resourceFactory == null) { throw new NullPointerException("resourceFactory is null"); } if (singleFactory == null) { throw new NullPointerException("singleFactory is null"); } if (disposeAction == null) { throw new NullPointerException("disposeAction is null"); } return create(new SingleOnSubscribeUsing(resourceFactory, singleFactory, disposeAction, disposeEagerly)); } /** * Returns a Single that delays the subscription to this Single * until the Observable completes. In case the {@code onError} of the supplied observer throws, * the exception will be propagated to the downstream subscriber * and will result in skipping the subscription of this Single. * *

*

*
Scheduler:
*
This method does not operate by default on a particular {@link Scheduler}.
*
* * @param other the Observable that should trigger the subscription * to this Single. * @return a Single that delays the subscription to this Single * until the Observable emits an element or completes normally. */ @Experimental public final Single delaySubscription(Observable other) { if (other == null) { throw new NullPointerException(); } return create(new SingleOnSubscribeDelaySubscriptionOther(this, other)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy