簡體   English   中英

如何使用Angular處理RxJS中的錯誤

[英]How to handle errors in RxJS using Angular

我正在使用一個Angular應用程序,該應用程序顯示了從RESTful API獲取的項目列表。 列表的內容取決於查詢。 可以通過填寫輸入字段,使用提交按鈕或將其添加為URL作為查詢參數來傳遞查詢。

為了確保一切正常運行並防止異步問題,我使用了RxJS

現在,我想知道如何處理錯誤,因為錯誤可能發生在流的中間,例如。 當HTTP請求失敗時。

查詢作為輸入流

這是兩個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中創建兩個新的流來解決此問題,一個流在成功時處理結果,一個在發生錯誤時處理結果。 查詢無效時的響應數據包含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來忽略錯誤,並確保流在出現錯誤后繼續。 但是我找不到正確地“處理”錯誤並將其顯示給最終用戶的方法。

在這種情況下是否有建議的方法來處理錯誤? 為此有必要創建兩個流,還是建議拋出異常?

重要的是,用戶必須知道出了點問題,並且在第一個錯誤發生后流不會停止。

捕獲邏輯的問題在於,它有效地終止了它之前的序列,這就是為什么如果在頂級流中使用它,它將在單個異常后停止的原因。 我建議您將catch邏輯包裝在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;
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM