簡體   English   中英

如何很好地向Angular RXJS Observable訂戶拋出錯誤

[英]How to nicely throw an error to an Angular RXJS Observable subscriber

對於下面的函數,我如何從“ BROKEN”引發錯誤,這樣它的訂戶可以很好地處理該錯誤,就像使用“ WORKS”代碼行一樣?

我所看到的是,“ Works”行巧妙地傳遞了此函數的訂戶的錯誤,而BROKEN行僅被炸毀而沒有被其訂戶處理。 我在Ionic項目,RXJS版本5.5.2和@ angular / common / http中的HttpClient中使用Angular(版本5.0.3)。

public makeRequest(requestParameters) {

  return Observable.create(observer => {

    let url = 'http://example.com/service/action?a=b';

    this.http.get(url,{withCredentials: true})
      .subscribe(data => {
        if(data["success"] !== true)
          observer.error("Unexpected result");//BROKEN
        else
          observer.next(data["payload"]);
      },
      err => {
        console.log('error: ' + err);
        observer.error(err);//WORKS
      });
    });
}

這是一個調用上述函數的示例:

public getStuffFromServer(){
  this.makeRequest({parameters go here}).subscribe(
      data => {
        //do something with the results
      },
      err => {
        //This never gets called from the 'BROKEN' code (but it does from the WORKS code
      }
    );
}

謝謝你的幫助!

因此問題似乎出在該行中:

if(data["success"] !== true)
    observer.error("Unexpected result");//BROKEN`

此時的訂閱尚未發生錯誤,實際上該訂閱已返回數據。

嘗試:

 observer.next(false);

或類似的東西。

好的,好像我在此頁面上找到了答案: https : //codingblast.com/rxjs-error-handling/

關鍵是使用地圖捕獲功能,如下所示:

public makeRequest(requestParameters) {

return Observable.create(observer => {
let url = 'http://example.com/service/action?a=b';
this.http.get(url,{withCredentials: true})
  .map(data => {
    if(data["success"] !== true)
      throw new Error("Something meaningful");
    return data["payload"];
   })
  .catch(err => {
    return Rx.Observable.throw(err);
   });
  .subscribe(data => {
      observer.next(data);
  },
  err => {
    console.log('error: ' + err);
    observer.error(err);
  });
});
}

希望這會對某人有所幫助。 謝謝所有回答或考慮過的人!

這是一個完整的工作示例,說明如何為設備和瀏覽器建立互聯網連接。 使用Angular 7和RxJs 6.3.3:

服務:

import {
  Injectable
} from '@angular/core';
import {
  Network
} from '@ionic-native/network';

import {
  Platform
} from 'ionic-angular';

import {
  Observable,
  fromEvent,
  merge,
  of
} from 'rxjs';

import {
  mapTo
} from 'rxjs/operators';

@Injectable()
export class NetworkService {

  private online$: Observable < boolean > = null;

  constructor(private network: Network, private platform: Platform) {
    this.online$ = Observable.create(observer => {
      observer.next(true);
    }).pipe(mapTo(true));
    if (this.platform.is('cordova')) {
      // on Device
      this.online$ = merge(
        this.network.onConnect().pipe(mapTo(true)),
        this.network.onDisconnect().pipe(mapTo(false)));
    } else {
      // on Browser
      this.online$ = merge( of (navigator.onLine),
        fromEvent(window, 'online').pipe(mapTo(true)),
        fromEvent(window, 'offline').pipe(mapTo(false))
      );
    }
  }

  public getNetworkType(): string {
    return this.network.type
  }

  public getNetworkStatus(): Observable < boolean > {
    return this.online$;
  }

}

無論您需要檢查的地方,只需導入服務並按以下方式使用:

...
    this.networkService.getNetworkStatus().subscribe((isConnected: boolean) => {
     console.log('Is it connected? '+isConnected);
    });
...

暫無
暫無

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

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