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

时间:2018-01-25 21:44:41

标签: angular ionic-framework error-handling rxjs observable

对于下面的函数,我怎么能从'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 :(得分:0)

所以问题似乎在于:

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

此时订阅未发生错误,实际上订阅已返回数据。

尝试:

 observer.next(false);

或类似的东西。

答案 1 :(得分:0)

好的,看起来我在这个页面上找到了答案: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);
  });
});
}

希望这会对某人有所帮助。谢谢大家的回答或想一想!

答案 2 :(得分:0)

这是一个完整的工作示例,说明如何为设备和浏览器建立Internet连接。 使用Angular 7和RxJs 6.3.3:

服务:

[1.2,3.5,41.2,2.9]

您需要检查的地方只要导入服务并按以下方式使用:

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

}