web-dev-qa-db-fra.com

Quelle est la différence entre Rx.Observable subscribe et forEach

Après avoir créé un observable comme ça

var source = Rx.Observable.create(function(observer) {...});

Quelle est la difference entre subscribe

source.subscribe(function(x) {});

et pour chaque

source.forEach(function(x) {});
46
Kevin Le - Khnle

Dans le spéc. ES7 , qui RxJS 5. suit (mais RxJS 4.0 ne le fait pas), les deux ne sont PAS identiques.

s'abonner

public subscribe(observerOrNext: Observer | Function, error: Function, complete: Function): Subscription

Observable.subscribe est l'endroit où vous ferez la plus grande partie de votre véritable traitement Observable. Il renvoie un jeton d'abonnement, que vous pouvez utiliser pour annuler votre abonnement. Ceci est important lorsque vous ne connaissez pas la durée des événements/séquences auxquels vous êtes abonné ou s'il vous faudra peut-être arrêter d'écouter avant une durée connue.

pour chaque

public forEach(next: Function, PromiseCtor?: PromiseConstructor): Promise

Observable.forEach renvoie une promesse qui sera résolue ou rejetée lorsque l’Observable sera terminé ou si des erreurs se produiront. Il est destiné à clarifier les situations dans lesquelles vous traitez une séquence observable de durée bornée/finie d'une manière plus "synchrone", telle que la compilation de toutes les valeurs entrantes, puis la présentation unique, en gérant la promesse.

Effectivement, vous pouvez agir sur chaque valeur, ainsi que sur les événements d'erreur et d'achèvement dans les deux sens. Donc, la différence fonctionnelle la plus significative est l'incapacité d'annuler une promesse.

59
shannon

Je viens de passer en revue le dernier code disponible. Techniquement, le code de foreach appelle en fait s’abonner à RxScala, RxJS et RxJava. Cela ne semble pas très différent. Ils ont maintenant un type de retour permettant à l'utilisateur de disposer d'un moyen d'arrêter un abonnement ou similaire.

Lorsque je travaille sur la version précédente de RxJava, l'abonnement a un retour d'abonnement et forEach est juste un vide. Ce que vous pouvez voir une réponse différente en raison des changements.

/**
 * Subscribes to the [[Observable]] and receives notifications for each element.
 *
 * Alias to `subscribe(T => Unit)`.
 *
 * $noDefaultScheduler
 *  
 * @param onNext function to execute for each item.
 * @throws Java.lang.IllegalArgumentException if `onNext` is null
 * @throws rx.exceptions.OnErrorNotImplementedException if the [[Observable]] tries to call `onError`
 * @since 0.19
 * @see <a href="http://reactivex.io/documentation/operators/subscribe.html">ReactiveX operators documentation: Subscribe</a>
 */
def foreach(onNext: T => Unit): Unit = {
    asJavaObservable.subscribe(onNext)
 }

def subscribe(onNext: T => Unit): Subscription = {
    asJavaObservable.subscribe(scalaFunction1ProducingUnitToAction1(onNext))
}

/**
 *  Subscribes an o to the observable sequence.
 *  @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
 *  @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
 *  @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
 *  @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
 */
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
  return this._subscribe(typeof oOrOnNext === 'object' ?
    oOrOnNext :
    observerCreate(oOrOnNext, onError, onCompleted));
};

/**
 * Subscribes to the {@link Observable} and receives notifications for each element.
 * <p>
 * Alias to {@link #subscribe(Action1)}
 * <dl>
 *  <dt><b>Scheduler:</b></dt>
 *  <dd>{@code forEach} does not operate by default on a particular {@link Scheduler}.</dd>
 * </dl>
 * 
 * @param onNext
 *            {@link Action1} to execute for each item.
 * @throws IllegalArgumentException
 *             if {@code onNext} is null
 * @throws OnErrorNotImplementedException
 *             if the Observable calls {@code onError}
 * @see <a href="http://reactivex.io/documentation/operators/subscribe.html">ReactiveX operators documentation: Subscribe</a>
 */
public final void forEach(final Action1<? super T> onNext) {
    subscribe(onNext);
}

public final Disposable forEach(Consumer<? super T> onNext) {
    return subscribe(onNext);
}