web-dev-qa-db-fra.com

Quelles sont les différences entre observables et promesses en JavaScript?

J'ai donc lu que les observables cherchaient à dépasser les promesses en termes d'utilisation dans certains MVC JavaScript à venir:

Quelle est la différence entre observables et promesses?

Mis à jour: excuses! enlevé ma déclaration de fausseté.

30
chrisjlee

Quelle est la différence entre observables et promesses?

Pour résumer, une promesse résout asynchrone une valeur single, une observable résout (ou émet) des valeurs multiples de manière asynchrone (dans le temps).

Exemples concrets:

  • Promesse: Réponse d'un appel Ajax
  • Observable: événements de clic

Plus d'informations peuvent être trouvées ici: http://reactivex.io/intro.html

j'ai lu que les observables cherchent à dépasser les promesses

Peu probable. Les observables sont peut-être la meilleure solution à certains problèmes, mais cela ne rend pas les promesses obsolètes (si c'est ce que vous voulez dire).

29
Felix Kling

Les promesses sont une représentation d'une valeur future . Les observables sont une représentation d'une quantité éventuellement infinie de valeurs. 

Les promesses vont déclencher l'extraction de cette valeur immédiatement après sa création. Les observables ne commenceront à produire des valeurs que lorsque vous vous y abonnerez. (À moins que ce soit une observation à chaud, mais cela dépasse le cadre de cette question)

Les promesses sont conçues pour représenter les appels AJAX. Les observables sont conçus pour représenter n'importe quoi: événements, données de bases de données, données d'appels ajax, séquences (éventuellement infinies), etc.

33
Moeri

Promises offre un mécanisme de rappel très simpliste, où Rx offre une abstraction puissante sur la programmation asynchrone. Un observable représente un flux de données auquel nous pouvons ensuite appliquer des opérateurs afin de définir le traitement des données entrantes.

Si tout ce que vous avez à faire est de faire une requête HTTP puis de mettre à jour un composant d'interface utilisateur, l'utilisation d'une promesse peut suffire.

Cependant, la plupart des applications ont tendance à avoir des besoins plus complexes que cela (même si ce n’est pas évident au premier abord). En prenant notre requête HTTP par exemple, voyons comment la modélisation de ceci en tant qu’observable et l’utilisation de certains opérateurs Rx peuvent nous aider:

-Si la requête HTTP est déclenchée par une action de l'utilisateur, nous voudrons peut-être éviter de lancer plusieurs requêtes HTTP (imaginez un utilisateur en train de taper dans un champ de recherche). Nous ne souhaitons pas déclencher une requête pour chaque frappe; nous pourrions donc vouloir étrangler notre recherche, de sorte que nous n'envoyons une requête que si l'utilisateur arrête de taper pendant 300 ms. De plus, si l’utilisateur tape un mot, attend 300 ms et ajoute un autre caractère, nous enverrons une requête HTTP ultérieure. Avec Promises, nous nous trouverions probablement dans une situation critique, car nous ne pouvons pas contrôler l’ordre dans lequel nous recevrons les réponses et nous ne pouvons pas annuler les anciennes demandes. Rx résout ce problème en nous permettant de Switch entre flux, ce qui appelle Dispose sur les anciens abonnements aux requêtes dont nous ne nous soucions plus. Nous pourrions également filtrer toutes les entrées de recherche non valides, par exemple le terme recherché est inférieur à 3 caractères.

-Support pour traiter avec Timeouts/traitement des erreurs. Supposons que notre requête HTTP échoue, Rx nous permet de facilement Réessayer faire la requête.

- Disons que plusieurs parties de notre application doivent émettre le même appel HTTP. Nous ne voulons probablement pas passer cet appel plus d’une fois. Nous pouvons exposer notre observable à plusieurs consommateurs et utiliser Replay pour s'assurer que l'appel est passé une fois et que le résultat est mis en cache pour les abonnés suivants. Nous pouvons même fournir un TimeSpan à rejouer, nous donnant un comportement de cache expirant.

-Abstraction puissante sur le threading grâce à l'utilisation de planificateurs, ce qui nous permet de contrôler la simultanéité. Mieux encore, nous pouvons utiliser des planificateurs de tests dans nos tests unitaires pour contrôler le temps, ce qui nous permet de simuler des temps morts, des conditions de course, etc.

Voici quelques exemples rapides pour démontrer ce qui est possible. La structure Rx compte de nombreux autres opérateurs pour prendre en charge tous les types de scénarios et la composabilité de Rx signifie que vous pouvez facilement combiner des opérateurs pour définir le comportement souhaité. Il est également facile de créer vos propres opérateurs réutilisables (par exemple, RetryAfterDelay).

En résumé, Rx peut faire tout ce que Promises peut faire, et bien plus encore. Je pense que dans les deux prochaines années, il y aura un changement continu vers Rx au lieu de Promises. 

Pour en savoir plus, je vous conseillerais de vous reporter à la section Observables du guide Angular 2 .

24
domino

comme dit dans Angular 2 guid

La conversion en promesse est souvent un bon choix lorsque vous souhaitez extraire un seul bloc de données. Ainsi, lorsque vous recevez les données, vous avez terminé.

Mais dans certains cas, les demandes ne sont pas toujours faites une fois. Vous pouvez lancer une demande, l'annuler et faire une demande différente avant que le serveur n'ait répondu à la première demande.

par exemple, dans un composant de recherche. Lorsque l'utilisateur saisit un nom dans une zone de recherche, vous allez effectuer des requêtes HTTP répétées à l'aide de cette requête.

Une séquence requête-annulation-nouvelle-requête est difficile à implémenter avec Des promesses, mais facile avec Observables.

donc si votre composant obtient des données avec une seule requête, c'est un bon choix d'utiliser Promise, mais s'il a une chaîne de requête request-cancel-new, utilisez observable

6
Parid0kht

Les observables sont souvent comparés aux promesses. Voici quelques différences clés:

Les observables sont déclaratifs; le calcul ne commence pas avant la souscription. Les promesses sont exécutées immédiatement lors de la création. Cela rend les observables utiles pour définir des recettes pouvant être exécutées chaque fois que vous avez besoin du résultat.

Les observables fournissent de nombreuses valeurs. Les promesses en fournissent un. Cela rend les observables utiles pour obtenir plusieurs valeurs au fil du temps.

Les observables font la distinction entre chaînage et abonnement. Les promesses ont seulement des clauses .then (). Cela rend les observables utiles pour créer des recettes de transformation complexes à utiliser par d'autres parties du système, sans provoquer l'exécution du travail.

Observables subscribe () est responsable du traitement des erreurs. Promises Poussez les erreurs aux promesses de l'enfant. Cela rend les observables utiles pour la gestion d'erreur centralisée et prévisible.

Meilleure explication par angular sur le site officiel: 

https://angular.io/guide/comparing-observables

1
asad mohd

Lorsque vous comprenez correctement Observables, les différences avec Promises sont assez évidentes. 

Le meilleur moyen de démystifier un concept compliqué consiste à le mettre en œuvre à partir de zéro. Voici une implémentation de Observable presque purement fonctionnelle et un exemple qui ne fonctionnerait pas avec Promises:

/*** Observable type ***/

// type constructor (of a product type)

const proType = name => cons => {
  const f = (k, ...args) =>
    Object.defineProperties({["run" + name]: k}, {
      [Symbol.toStringTag]: {value: name},
      [Symbol("args")]: {value: args}
    });

  return cons(f);
};

// value constructor

const Observable = proType("Observable")
  (Observable => k => Observable(k));

/*** Observer factory ***/

const Observer = observer => {
  let isUnsubscribed = false;

  return {
    next: function(x) {
      if (isUnsubscribed)
        throw new Error("unsubscribed");

      else {
        try {
          return observer.next(x);
        }

        catch(e) {
          isUnsubscribed = true;
          this.cancel();
          throw e;
        }
      }
    },

    error: function(e) {
      if (isUnsubscribed)
        throw new Error("unsubscribed");

      else {
        try {
          return observer.error(e);
        }

        catch(e_) {
          isUnsubscribed = true;
          this.cancel();
          throw e_;
        }
      }
    },

    complete: function() {
      if (isUnsubscribed)
        throw new Error("unsubscribed");

      else {
        try {
          const r = observer.complete();
          this.cancel();
          return r;
        }

        catch(e) {
          isUnsubscribed = true;
          cancel();
          throw e;
        }
      }
    }
  };
};

/*** combinators + auxiliary functions ***/

const subscribe = observable => handlers => {
  const observer = Observer(handlers),
    cancel = observable.runObservable(observer);

  observer.cancel = cancel;
  return cancel;
};

const obsMap = f => observable =>
  Observable(observer => {
    const mapObserver = {
      next: x => observer.next(f(x)),
      error: e => observer.error(e),
      complete: () => observer.complete()
    };

    return observable.runObservable(mapObserver);
  });

/*** main ***/

// create an Observable instance

const numStream = Observable(observer => {
  let i = 0;

  const timer = setInterval(() => {
    observer.next(i++);
  }, 1000);
  
  return () => clearTimeout(timer);
});

// map a function over it

const squaredNumStream =
  obsMap(x => x * x) (numStream);

// run the observable

const cancel = subscribe(squaredNumStream) ({
  next: x => console.log(x),
  error: e => console.error(e),
  complete: () => console.log("finished")
});

// cancel it

setTimeout(cancel, 11000);

Dans l'exemple ci-dessus, la ObservablesquaredNumStream émet un flux de valeurs théoriquement infinies de manière asynchrone. Vous ne pouvez pas faire cela avec Promises, car ils représentent une seule valeur future.

J'aurais facilement pu souscrire à une autre squaredNumStream sans que les deux instances se gênent l'une l'autre. En effet, les Observables sont unicast, alors que Promises sont multicast.

squaredNumStream ne s'exécute pas au moment de la déclaration, mais uniquement après la souscription, car Observables est évalué paresseusement. Promises sont quant à eux évalués avec impatience, c'est-à-dire qu'ils commencent à s'exécuter dès que vous les créez.

Et enfin, les variables Observables sont annulables par conception, alors que les variables Promises sont difficiles à annuler en raison de leur sémantique unicast.

0
user10675354