Подтвердить что ты не робот

Преобразовать обещание в наблюдаемое

Я пытаюсь обернуть голову вокруг наблюдаемых. Мне нравится, как наблюдаемые решения решают проблемы развития и читабельности. Как я читаю, преимущества огромны.

Наблюдаемые на HTTP и коллекциях, кажется, прямо вперед. Как я могу преобразовать что-то вроде этого в наблюдаемый шаблон.

Это из моего сервисного компонента, чтобы обеспечить аутентификацию. Я бы предпочел, чтобы это работало как другие HTTP-сервисы в Angular2 - с поддержкой данных, обработчиков ошибок и завершения.

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;
    // ...
  });

Любая помощь здесь будет высоко ценится. Единственным альтернативным решением, которое у меня было, было создание EventEmitter. Но я думаю, что это ужасный способ сделать что-то в разделе услуг

4b9b3361

Ответ 1

Если вы используете RxJS 6.0.0:

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

Ответ 2

попробуйте это:

import { Observable } from "rxjs/Observable";

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

вы можете найти полную ссылку на оператора fromPromise здесь.

Ответ 3

от

Используйте from, чтобы напрямую преобразовать ранее созданное Обещание в Observable.

import { from } from 'rxjs';

// getPromise() will only be called once
const observable$ = from(getPromise());

Поскольку внутреннее Обещание уже создано (или будет создано в то же время, что и Наблюдаемое), тело Обещания выполняется или уже было разрешено при создании Наблюдаемого. Если внутреннее Обещание уже разрешило нового подписчика на наблюдаемый объект, он немедленно получит свое значение (getPromise() больше не будет вызываться).

отложить

Используйте defer с заводской функцией Promise в качестве входных данных, чтобы отложить создание и преобразование Promise в Observable.

import { defer } from 'rxjs';

// getPromise() will be called every time someone subscribes to the observable$
const observable$ = defer(() => getPromise());

Отличие от from состоит в том, что defer ожидает подписчика и только затем создает новое Promise, вызывая данную функцию фабрики Promise. Это полезно, когда вы хотите создать Observable, но не хотите, чтобы внутреннее Обещание выполнялось сразу. Внутреннее Обещание будет выполнено только тогда, когда кто-то подпишется на Observable. Каждый подписчик также получит свой новый Observable.

Разница между from и defer в примере: https://stackblitz.com/edit/rxjs-6rb7vf

const getPromise = val => new Promise(resolve => {
  console.log('Promise created for', val);
  setTimeout(() => resolve('Promise Resolved: ${val}'), 5000);
});

// the execution of getPromise('FROM') starts here, when you create the promise inside from
const fromPromise$ = from(getPromise('FROM'));
const deferPromise$ = defer(() => getPromise('DEFER'));

fromPromise$.subscribe(console.log);
// the execution of getPromise('DEFER') starts here, when you subscribe to deferPromise$
deferPromise$.subscribe(console.log);

Ответ 4

Вы также можете использовать Subject и вызывать его функцию next() из обещания. Смотрите образец ниже:

Добавьте код, как показано ниже (я использовал сервис)

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);
          // ...
        });
    }

  }
}