web-dev-qa-db-fra.com

Convertir une promesse en observable

J'essaie de faire le tour des observables. J'aime la façon dont les observables résolvent les problèmes de développement et de lisibilité. En lisant, les avantages sont immenses. 

Les observables sur HTTP et les collections semblent être simples. Comment puis-je convertir quelque chose comme ceci en motif observable.

Cela provient de mon composant de service, pour fournir une authentification. Je préférerais que cela fonctionne comme les autres services HTTP dans Angular2 - avec prise en charge des gestionnaires de données, d'erreurs et d'achèvement.

firebase.auth().createUserWithEmailAndPassword(email, password)
        .then(function(firebaseUser) {
             // do something to update your UI component
             // pass user object to UI component
        })
        .catch(function(error) {
             // Handle Errors here.
             var errorCode = error.code;
             var errorMessage = error.message;
             // ...
        });

Toute aide ici serait très appréciée. La seule solution alternative que j'avais était de créer EventEmitters. Mais je suppose que c'est une façon terrible de faire les choses dans la section des services

95
Krishnan Sriram

Si vous utilisez RxJS 6.0.0:

import { from } from 'rxjs';
const observable = from(promise);
114
Guillaume

essaye ça:

var subscription = Observable.fromPromise(
    firebase.auth().createUserWithEmailAndPassword(email, password)
);
subscription.subscribe(firebaseUser => /* Do anything with data received */,
                       error => /* Handle error here */);

vous pouvez trouver une référence complète à l'opérateur fromPromise ici

105
Godfather

de

Utilisez from pour convertir directement une promesse en observable. from attendra immédiatement que la promesse soit résolue. 

import { from } from 'rxjs';

const observable = from(promise);

reporter

Utilisez defer avec une fonction d'usine Promise comme entrée pour différer la création et la conversion d'une promesse en observable. 

import { defer } from 'rxjs';

// getPromise has no parameters and returns a Promise
const observable = defer(getPromise)

// getPromise has parameters and returns a Promise
const observable = defer(() => getPromise(myParameters));

La différence par rapport à from est que defer attend un abonné et ne génère alors qu'un nouvel observable en appelant la fonction de fabrique Promise donnée. Ainsi, la promesse interne n'est «exécutée» que lorsque quelqu'un s'abonne à l'Observable au lieu de directement lorsque l'Observable est créé, comme c'est le cas avec from. Chaque abonné recevra également son propre nouvel observable.

La différence entre from et defer dans un exemple: https://stackblitz.com/edit/rxjs-xcudxb

2
fridoo

Vous pouvez également utiliser un Subject et déclencher sa fonction next () depuis promesse. Voir échantillon ci-dessous:

Ajouter le code comme ci-dessous (j'ai utilisé le service)

class UserService {
  private createUserSubject: Subject < any > ;

  createUserWithEmailAndPassword() {
    if (this.createUserSubject) {
      return this.createUserSubject;
    } else {
      this.createUserSubject = new Subject < any > ();
      firebase.auth().createUserWithEmailAndPassword(email,
          password)
        .then(function(firebaseUser) {
          // do something to update your UI component
          // pass user object to UI component
          this.createUserSubject.next(firebaseUser);
        })
        .catch(function(error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          this.createUserSubject.error(error);
          // ...
        });
    }

  }
}

Créer un utilisateur à partir d'un composant comme ci-dessous

class UserComponent {
  constructor(private userService: UserService) {
    this.userService.createUserWithEmailAndPassword().subscribe(user => console.log(user), error => console.log(error);
    }
  }
0
Shivang Gupta