web-dev-qa-db-ja.com

約束を観測可能に変換

私は天文台を頭に巻きつけるようにしています。私は観測量が開発と読みやすさの問題を解決する方法が大好きです。私が読んだように、利益は計り知れません。

HTTPとコレクションの観測量は単純明快です。どうすればこのようなものを観察可能なパターンに変換できますか。

これは、認証を提供するための私のサービスコンポーネントからのものです。これはAngular 2の他のHTTPサービスと同じように機能することを望みます - データ、エラー、および補完ハンドラをサポートします。

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

ここにどんな助けでも大いに感謝されるでしょう。私が持っていた唯一の代替解決策はEventEmittersを作成することでした。しかし、私はそれがサービスのセクションで物事を行うためのひどい方法だと思います

124
Krishnan Sriram

RxJS 6.0.0を使用している場合

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

これを試して:

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

fromPromise演算子 への完全な参照は、ここ にあります。

107
Godfather

から

from を使用して、以前に作成したPromiseをObservableに直接変換します。

import { from } from 'rxjs';

const observable = from(promise);

内側のPromiseはすでに作成されている(またはObservableと同時に作成される)ので、Promiseの本体は実行中であるか、Observableが作成された時点ですでに解決されています。内側のPromiseがObservableへの新しいSubscriberをすでに解決している場合は、すぐにその値を取得します。

延期する

Promiseの作成とObservableへの変換を延期するには、入力として defer を使用します。

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));

fromとの違いは、deferはサブスクライバを待機してから、指定されたPromiseファクトリ関数を呼び出すことによってのみ新しいPromiseを作成することです。これは、Observableを作成したいが内部のPromiseをすぐに実行したくない場合に便利です。内側の約束は、誰かがオブザーバブルを購読するときにのみ実行されます。各加入者はまたそれ自身の新しいObservableを得るでしょう。

例でのfromdeferの違いは次のとおりです。 https://stackblitz.com/edit/rxjs-yye14a

8
fridoo

件名を使用して、その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);
          // ...
        });
    }

  }
}

以下のようにコンポーネントからユーザーを作成します

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