【问题标题】:How to nicely throw an error to an Angular RXJS Observable subscriber如何很好地向 Angular RXJS Observable 订阅者抛出错误
【发布时间】:2018-07-05 06:20:07
【问题描述】:

对于下面的函数,我怎样才能从“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
      }
    );
}

感谢您的帮助!

【问题讨论】:

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


【解决方案1】:

所以问题似乎出在这一行:

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

此时订阅没有出错,实际上订阅已经返回数据。

试试:

 observer.next(false);

或类似的东西。

【讨论】:

  • 在这种情况下,如果 data["success"] 为 false,则服务器上会抛出异常。我打算将该异常的详细信息传递给所有订阅者,而不会让他们以两种方式查找失败。不过谢谢你的想法!
【解决方案2】:

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

关键是像这样使用 ma​​pcatch 函数:

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

希望这会对某人有所帮助。感谢所有回答或考虑过的人!

【讨论】:

  • 我收到此错误 TypeError: Observable.throw is not a function
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 2018-09-08
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多