首页 文章

如何很好地将错误抛给Angular RXJS Observable订阅者

提问于
浏览
0

对于下面的函数,我怎么能从'BROKEN'中抛出一个错误,就像它的订阅者可以像'WORKS'代码行一样很好地处理它?

我所看到的是'Works'行整齐地传递了该函数的订阅者的错误,而BROKEN行只是在没有被其订阅者处理的情况下爆炸 . 我在Ionic项目中使用Angular(版本5.0.3),RXJS版本5.5.2和@ angular / common / http中的HttpClient .

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

谢谢你的帮助!

3 回答

  • 0

    所以问题似乎在于:

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

    此时的订阅没有遇到错误,实际上订阅已返回数据 .

    尝试:

    observer.next(false);
    

    或类似的东西 .

  • 0

    好的,看起来我在这个页面上找到了答案:https://codingblast.com/rxjs-error-handling/

    关键是使用 mapcatch 函数,如下所示:

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

    希望这会对某人有所帮助 . 谢谢大家的回答或者给予了一些思考!

  • 0

    这是一个完整的工作示例,如何获得设备和浏览器的互联网连接 . 使用Angular 7和RxJ 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);
        });
    ...
    

相关问题