1

RESTful API から取得したアイテムのリストを表示する Angular アプリケーションに取り組んでいます。リストの内容はクエリによって異なります。クエリは、入力フィールドに入力するか、送信ボタンを使用するか、クエリ パラメータとして URL に追加することで渡すことができます。

すべてが正常に実行され、非同期の問題が発生しないようにするために、私はRxJSを使用しています。

エラーはストリームの途中で発生する可能性があるため、エラーをどのように処理できるか疑問に思っています。HTTP リクエストが失敗したとき。

入力ストリームとしてのクエリ

これらは 2 つでObservables、どちらも一連のクエリを送信します。

// first observable for the submit button
submitFormObservable = $scope.$createObservableFunction('search');

// second observable for when the input value changes
inputObservable = $scope.$toObservable('query')
  .map(function (change) {
    return change.newValue;
  });

結果のフェッチ

以下Observableは、クエリが変更されたときにトリガーされ、API から結果をフェッチします。

var mainStream = Rx.Observable.merge([submitFormObservable, inputObservable])
  .where(function (query) {
    return query && query.length > 0;
  })
  .debounce(400)
  .distinctUntilChanged()
  .select(getResultsForQuery)
  .switchLatest();

エラー処理

たとえば、エラーを処理する方法がわかりません。エラーがgetResultsForQueryスローされます。結果の代わりにエラーを表示したいのですが、 がObservable新しいイベントを処理できないようにします。

現在、Observable から 2 つの新しいストリームを作成することで解決しました。1 つは成功時の結果を処理するためのもので、もう 1 つはエラーが発生した場合のものです。クエリが無効だった場合の応答データには、errorプロパティが含まれています。

成功の流れ

// stream containing the album information from LastFm
mainStream
  .filter(function (response) {
    return !response.data.error;
  })
  .map(function (response) {
    return response.data.result;
  })
  .subscribe(function (result) {
    $scope.error = undefined;
    $scope.result = result;
  });

エラー ストリーム

mainStream
  .filter(function (response) {
      return response.data.error;
    })
   .map(function (response) {
      return response.data;
  });
  .subscribe(function (error) {
    $scope.result = [];
    $scope.error = error;
  });

可能な解決策

  1. エラーのスローとキャッチについて読んだことがありますが、ここでの問題は、最初のエラーの後にストリームが停止したように見え、新しいイベントをトリガーしないことです。

  2. エラーを無視し、エラー後にストリームが継続することを確認するための使用方法onErrorResumeNextドキュメントに記載されています。しかし、エラーを正しく「処理」してエンド ユーザーに表示する方法が見つかりません。

質問

このような状況でエラーを処理する方法について推奨されるアプローチはありますか? これには 2 つのストリームを作成する必要がありますか、それとも例外をスローすることをお勧めしますか?

何か問題が発生したことをユーザーが認識し、最初のエラーの後でストリームが停止しないことが重要です。

4

1 に答える 1

4

キャッチ ロジックの問題は、その前にシーケンスを効果的に終了させることです。これが、トップ レベル ストリームで使用すると、単一の例外の後で停止する理由です。キャッチ ロジックを 内にラップすることをお勧めしますflatMapLatest。次に、内部ストリームをキャッチし、データを変換して、ダウンストリームobserversが期待するものに適合させることができます。

このようなもの:

var mainStream = Rx.Observable.merge([submitFormObservable, inputObservable])
  .where(function (query) {
    return query && query.length > 0;
  })
  .debounce(400)
  .distinctUntilChanged()
  .selectSwitch(function(input) {
    return getResultsForQuery(input)
            .map(function(response) {
              return {result : response.data.result};
            })
            .catch(function(e) {
              return Rx.Observable.just({error : error});
            });
  });

mainStream.subscribe(function(r) {
  $scope.result = r.result || [];
  $scope.error = r.error;
});
于 2015-07-16T17:24:54.000 に答える