|
19 | 19 | /**
|
20 | 20 | * Provides a mechanism for receiving push-based notifications.
|
21 | 21 | * <p>
|
22 |
| - * After an Observer calls an {@link Observable}'s {@link Observable#subscribe subscribe} method, |
23 |
| - * first the Observable calls {@link #onSubscribe(Disposable)} with a {@link Disposable} that allows |
24 |
| - * cancelling the sequence at any time, then the |
25 |
| - * {@code Observable} may call the Observer's {@link #onNext} method any number of times |
| 22 | + * When an {@code Observer} is subscribed to an {@link ObservableSource} through the {@link ObservableSource#subscribe(Observer)} method, |
| 23 | + * the {@code ObservableSource} calls {@link #onSubscribe(Disposable)} with a {@link Disposable} that allows |
| 24 | + * disposing the sequence at any time, then the |
| 25 | + * {@code ObservableSource} may call the Observer's {@link #onNext} method any number of times |
26 | 26 | * to provide notifications. A well-behaved
|
27 |
| - * {@code Observable} will call an Observer's {@link #onComplete} method exactly once or the Observer's |
| 27 | + * {@code ObservableSource} will call an {@code Observer}'s {@link #onComplete} method exactly once or the {@code Observer}'s |
28 | 28 | * {@link #onError} method exactly once.
|
29 |
| - * |
| 29 | + * <p> |
| 30 | + * Calling the {@code Observer}'s method must happen in a serialized fashion, that is, they must not |
| 31 | + * be invoked concurrently by multiple threads in an overlapping fashion and the invocation pattern must |
| 32 | + * adhere to the following protocol: |
| 33 | + * <p> |
| 34 | + * <pre><code> onSubscribe onNext* (onError | onComplete)?</code></pre> |
| 35 | + * <p> |
| 36 | + * Subscribing an {@code Observer} to multiple {@code ObservableSource}s is not recommended. If such reuse |
| 37 | + * happens, it is the duty of the {@code Observer} implementation to be ready to receive multiple calls to |
| 38 | + * its methods and ensure proper concurrent behavior of its business logic. |
| 39 | + * <p> |
| 40 | + * Calling {@link #onSubscribe(Disposable)}, {@link #onNext(Object)} or {@link #onError(Throwable)} with a |
| 41 | + * {@code null} argument is forbidden. |
| 42 | + * <p> |
| 43 | + * The implementations of the {@code onXXX} methods should avoid throwing runtime exceptions other than the following cases |
| 44 | + * (see <a href="https://github.com/reactive-streams/reactive-streams-jvm#2.13">Rule 2.13</a> of the Reactive Streams specification): |
| 45 | + * <ul> |
| 46 | + * <li>If the argument is {@code null}, the methods can throw a {@code NullPointerException}. |
| 47 | + * Note though that RxJava prevents {@code null}s to enter into the flow and thus there is generally no |
| 48 | + * need to check for nulls in flows assembled from standard sources and intermediate operators. |
| 49 | + * </li> |
| 50 | + * <li>If there is a fatal error (such as {@code VirtualMachineError}).</li> |
| 51 | + * </ul> |
| 52 | + * <p> |
| 53 | + * Violating Rule 2.13 results in undefined flow behavior. Generally, the following can happen: |
| 54 | + * <ul> |
| 55 | + * <li>An upstream operator turns it into an {@link #onError} call.</li> |
| 56 | + * <li>If the flow is synchronous, the {@link ObservableSource#subscribe(Observer)} throws instead of returning normally.</li> |
| 57 | + * <li>If the flow is asynchronous, the exception propagates up to the component ({@link Scheduler} or {@link java.util.concurrent.Executor}) |
| 58 | + * providing the asynchronous boundary the code is running and either routes the exception to the global |
| 59 | + * {@link io.reactivex.plugins.RxJavaPlugins#onError(Throwable)} handler or the current thread's |
| 60 | + * {@link java.lang.Thread.UncaughtExceptionHandler#uncaughtException(Thread, Throwable)} handler.</li> |
| 61 | + * </ul> |
| 62 | + * From the {@code Observable}'s perspective, an {@code Observer} is the end consumer thus it is the {@code Observer}'s |
| 63 | + * responsibility to handle the error case and signal it "further down". This means unreliable code in the {@code onXXX} |
| 64 | + * methods should be wrapped into `try-catch`es, specifically in {@link #onError(Throwable)} or {@link #onComplete()}, and handled there |
| 65 | + * (for example, by logging it or presenting the user with an error dialog). However, if the error would be thrown from |
| 66 | + * {@link #onNext(Object)}, <a href="https://github.com/reactive-streams/reactive-streams-jvm#2.13">Rule 2.13</a> mandates |
| 67 | + * the implementation calls {@link Disposable#dispose()} and signals the exception in a way that is adequate to the target context, |
| 68 | + * for example, by calling {@link #onError(Throwable)} on the same {@code Observer} instance. |
| 69 | + * <p> |
| 70 | + * If, for some reason, the {@code Observer} won't follow Rule 2.13, the {@link Observable#safeSubscribe(Observer)} can wrap it |
| 71 | + * with the necessary safeguards and route exceptions thrown from {@code onNext} into {@code onError} and route exceptions thrown |
| 72 | + * from {@code onError} and {@code onComplete} into the global error handler via {@link io.reactivex.plugins.RxJavaPlugins#onError(Throwable)}. |
30 | 73 | * @see <a href="http://reactivex.io/documentation/observable.html">ReactiveX documentation: Observable</a>
|
31 | 74 | * @param <T>
|
32 | 75 | * the type of item the Observer expects to observe
|
|
0 commit comments