インフラジスティックス・ジャパン株式会社Blog

インフラジスティックス・ジャパン株式会社のチームメンバーが技術トレンド、製品Tips、サポート情報からライセンス、日々の業務から感じることなど、さまざまなトピックについてお伝えするBlogです。

Angular Observable vs Angular Promise ~ それぞれの違いと使い方~

Angularのデータ管理には、主にObservablesとPromisesの2種類があり、どちらもJavaScriptで非同期なコードを管理することができます。一見すると、ObservablesはPromisesより高度な代替品とみなされます。しかし、実際には両者は全く異なるものです。別々のAPIを持ち、異なる動機を持ち、JavaScriptで非同期モデルを扱うための異なる方法を提供するなど、Angular ObservablesとAngular Promisesはそれぞれ独自の力を持っています。

あなたのAngularプロジェクトにどちらがふさわしいかを知るにはどうしたらよいでしょうか?

詳しく説明し、それぞれの実装を比較し、機能、メリットとデメリットを確認しましょう。その上で、私たちのローコードツールApp Builder™でAngular ObservablesとAngular Promisesを使い、非同期イベントを簡単かつ迅速に処理できるようにする方法を紹介します。

この記事はインフラジスティックス本社により作成された英文記事の翻訳により作成されました。
原文は以下よりご確認いただけます。
Desislava Dincheva 2022.4 / Angular Observable vs Angular Promise: Differences, Uses & How To Build Them https://www.infragistics.com/community/blogs/b/infragistics/posts/angular-observable-vs-angular-promise

AngularのPromiseとは?

AngularのPromiseは、コールバックを使用する非同期関数を実行する簡単な方法を提供し、同時に1つの値を発行して完了(resolve または reject)させます。Angular Promiseを使用すると、APIから1つのイベントを発信することが可能になります。そして、コントローラ(またはディレクティブ)は、最大3つのコールバック(成功、エラー、および/または通知)を登録することで、それを引き受けます。

Angular Promiseには、次の4つの状態があります。

  • 成功(fulfilled) - アクションが実行されました。
  • 失敗(rejected) - アクションが失敗しました。
  • 待機(pending) - アクションがまだ成功または失敗していない状態です。
  • 不変(settled) - アクションが実行されるか拒否されます。

覚えておくべきことは、Angular PromiseはObservableと比較してより受動的で、一度開始するとキャンセルすることができないということです。つまり、Promiseのコンストラクタ(コントローラやディレクティブ)にコールバックを渡すと、その関数を解決するか拒否するかのどちらかになります。

そして、Angular Promiseにはいくつかのデメリットがあります。

  • プロミスはキャンセルできないので、コールバックがエラーか成功を返すまで待つ必要がある。 = エラーは子プロミスに送られるため、一元的で予測可能なエラー処理には向いていない。
  • 操作を提供しない。
  • プロミスは非同期な値を一度だけ実行する。
  • 時間をかけて複数の値を実行することはできない。
  • 大規模なアプリケーションでは管理が難しくなる。
  • リトライができない。

AngularでPromiseを作成するには?

AngularでPromiseを作るには、「new Promise(function)」構文を使うだけです。Promiseのコンストラクタはパラメータとして関数を受け取り、その内部関数はパラメータとしてresolveとrejectを受け取ります。

以下のコードを見てみましょう。

Angular Promiseの作成方法がわかったので、これを使って非常に簡単なシナリオを実装してみましょう。作成されたPromiseは、数字が素数かどうかを検証するのに役立ちます。

そして最後に、この方法を実用化するために、次のような方法でPromiseを処理することにします。

AngularのObservableとは?

Observablesは、開発者が関数を非同期および同期で実行できるようにすることで、より多くの機能を提供します。

Observablesは値のストリームをあらわし、0、1、または複数のイベントを扱うことができ、それぞれに対して同じAPIを使用します。

私が個人的にAngular Observablesで気に入っているのは、retry()やreplay()、map、forEach、reduceなどのコーディングを簡単にする演算子がたくさんあることです。

Angular Promisesと同じように、AngularのObservablesにもデメリットがあります。

  • Observablesはブラウザでネイティブにサポートされているわけではありません。
  • ObservablesはRxJSのオペレータが新しいテーラードストリームの値を取得することを必要とします。
  • observableを使ったコードのデバッグは、少し難しいかもしれません。
  • RxJSのコードをテストするために、余分なツールやテクニックのノウハウを持っている必要があります。

AngularでObservableを作成するには?

AngularでObservableを作成するには、まずrxjsからObservableをインポートする必要があります。

新しいObservableを作成するには、そのコンストラクタを使用し、サブスクリプション時に実行されるロジックを追加するだけです。この例では、グリッドコンポーネント用の優れたデータソースを返すObservableを作成することにします。

あとは、作成したObservableをサブスクライブして、受け取ったデータをデータソースとしてGridコンポーネントにバインドするだけです。

observable を使用するための素晴らしい、より有意義な例は、リモートデータで IgxGrid を使用することです。

この例でわかるように、コンポーネントがレンダリングされるとき、データの小さな塊だけが最初に取得され、スクロールやデータ操作が行われるたびに、データの新しい断片が取得されます。このany[]型のobservableは、非同期のAngularパイプを使ってグリッドに直接バインドされています。非同期パイプはObservableやPromiseを購読し、それが発信した最新の値を返します。

サンプルはこちらから

App BuilderでAngular ObservableとPromiseを使うには?

Observablesを使用する最も一般的なシナリオは、データを何らかのコンポーネントにバインドする必要がある場合です。データを取得するためには、HttpClientを使用してhttpリクエストを行う必要がある。これを行う最良の方法は、別のサービスに持ち出すことです。全てのHttpClientのメソッドは、何かのRxJS Observableを返します。 一般的に、Observableは時間をかけて複数の値を返すことができますが、HttpClientのObservableは常に1つの値を出力して終了し、二度と出力することはありません。

App Builderでは、コンポーネントをデータソースにバインドすることは簡単で直感的です。現在、定義済みのデータソースの1つを使用するために、以下のオプションから選択することができます。

  • JSONファイルをアップロードするか、データを含むJSONファイルへのURLを追加する
  • サーバーのすべてのエンドポイントが記述されたSwagger定義ファイルを追加/アップロードし、そこから実際のデータを直接取得する

その後、どの方法を選んだとしても、propsパネルのDataドロップダウンを使って、データをコンポーネント(例えばAngularグリッド)にバインドすることができます。

次に、Angularで生成されたコードを見てみましょう。データの取得はhttpのgetメソッドを使用して実行される別のサービスを提供します。

そして、MasterViewComponentのtsファイルで、データサービスが実行したサブスクリプションを見ることができます。これをベースに、必要に応じてさらに複雑なシナリオを実行することができます。

Angular Observable vs Promise: 何が違うのか?

AngularのObservablesとPromiseの違いを示すために、表を作成しました。こうすることで、非常に簡潔な方法で比較することができます。

ANGULAR OBSERVABLES   ANGULAR PROMISES
同期・非同期両方のイベントを扱える 非同期のデータリターンしか扱えない
0、1、または複数の値を一定期間に渡って出力し、完了する(複数のパイプラインでデータをストリームする) 一度に1つの値しか出力しない(パイプラインは1本のみ)
map, filter, reduce, retry(), or replay(), map, forEachなどの操作を提供する 演算子を提供しない
unsubscribe()メソッドを使用してキャンセル可能。つまり、リスナーはそれ以上値を受け取らない。  キャンセルできない
遅延型、つまりユーザーがストリームを購読した後にプロデューサー関数が起動する Eager、すなわち、Promise コールバックは、.then や .catch なしで、定義された時点で直ちに一度だけ実行される 
サブスクライバーはエラーを処理する エラーを子 Promise にプッシュする

どうやら、AngularのObservableとPromiseの比較では、Observableが勝っているようです。では、Promiseを使う正当な理由はあるのでしょうか?もちろんです。

まず、Observableには一定のコストがかかります。先に述べたように、ブラウザでネイティブにサポートされていません。つまり、RxJSライブラリを実装する必要があります。そして、RxJSは非同期やコールバックベースのコードを作成するのに役立ちますが、そのバンドルサイズは17.4kbを超えることがあります。

次に、あなたのAngularアプリ(英語リンク)がデフォルトで非同期である場合、すべての非同期関数とイベントを処理するには、Angular Promiseを使うより他に方法はありません。そうでしょうか?

次に、もしあなたがリアクティブスタイルを使いたくない、または値のストリームやキャンセル可能なイベントに関心がないのであれば、AngularのPromiseを使うことをお勧めします。

最後に、フル機能のAngular UIグリッドをゼロから作成する方法を学ぶために、非常に詳細で役立つAngular UI データグリッドチュートリアルを最近公開しました。ですので、そちらもご覧になってみてください。以下をクリックしてください。

youtu.be