【问题标题】:How to keep observable alive after error in RxJS 6 and Angular 6在 RxJS 6 和 Angular 6 出错后如何保持 observable 存活
【发布时间】:2019-02-21 12:59:48
【问题描述】:

任何人都可以帮助解决this._getReactions$.next()this.http.get(...) 出现错误时无法工作的情况。我想保持 observable 活着以接受下一个输入。

private _getReactions$: Subject<any> = new Subject();

 constructor() {
  this._getReactions$
  .pipe(
    switchMap(() => {
        return this.http.get(...)
        // http request 
    }),
    catchError(error => {
      console.log(error);
      return empty();
    })
  )
  .subscribe(data => {
      console.log(data)
      //results handling
  });
 }

onClick() {
  this._getReactions$.next();
}

【问题讨论】:

标签: angular rxjs angular6 rxjs6


【解决方案1】:

如果 observable 死了,它会调用它的错误处理程序并且它们已关闭,您无法通过它们发送任何内容,这意味着它们已关闭,包括间隔在内的所有上游都已死。

如果我们想活下去。

屏蔽主观察者链是解决方案
将 catch 放入 switchmap 每当触发请求时switchmap 创建 ajax 可观察对象,这次使用 catch.
switchmap 的行为表明我的来源 还没有完成所以我真的不在乎孩子是否 完成我会继续。

 constructor() {
  this._getReactions$
    .pipe(tap(value => { this.loading = true; return value }),
      switchMap(() => {
        return this.http.get(...).pipe(
          catchError((error) => this.handleError(error)))
        // http request
      }),
    )
    .subscribe(data => {
      console.log(data)
      //results handling
      this.error = false;
      this.loading = false
    });
}

private handleError(error: HttpErrorResponse) {

  this.error = true;
  console.log(error)
  this.loading = false
  return empty();

Live Demo

Detailed Info

PS:嵌套在任何flattening 运算符中,例如mergeMapconcatMapexhaustMap 和其他展平运算符也可以。

【讨论】:

  • 感谢您的回复。我无法在handleError 方法中访问this.loading。你能帮我解决这个问题吗? ` private handleError(error: HttpErrorResponse) { if (error.error instanceof ErrorEvent) { } else { this.loading = false; this.error = true; } 返回空(); }`
  • @Krish 我已经更新了我的答案,stackblitz 请检查一下:)
  • 您可以使用@Vikas 在您的 HttpInterceptor (HttpClient) 中显示的机制来避免您的组件和/或服务中出现重复代码。
【解决方案2】:

我已经为所有请求

解决了这个问题

创建一个将执行所有请求的加载器文件

loader.ts

import { Observable, Subject, Subscription, EMPTY } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs/operators';

export class Loader<T1, T> {
  private _requestQueue: Subject<T1>;
  private _errorQueue: Subject<Error>;
  private _resultQueue: Observable<T>;
  private _loaded = false;

  constructor(loaderFunction: (T1) => Observable<T>) {
    this._requestQueue = new Subject<T1>();
    this._errorQueue = new Subject<Error>();
    this._resultQueue = this._requestQueue.pipe(
      switchMap(_ => {
        this._loaded = false;
        return loaderFunction(_).pipe(
          catchError(error => {
            this._loaded = true;
            this._errorQueue.next(error);
            // Returning EMPTY observable won't complete the stream
            return EMPTY;
          })
        );
      }),
      map(_ => {
        this._loaded = true;
        return _;
      }),
    );
  }

  public load(arg?: T1): void {
    this._requestQueue.next(arg);
  }

  public subscribe(successFn: (T) => any, errorFn?: (error: any) => void, 
    completeFn?: () => void): Subscription {
    
    this._errorQueue.subscribe(err => {
      errorFn(err);
    });
    return this._resultQueue.subscribe(successFn, null, completeFn);
  }

  public complete() {
    this._requestQueue.complete();
    this._errorQueue.complete();
  }
  
  get loaded(): boolean {
    return this._loaded;
  }
}

在您将执行请求的其他文件中(简单)

export class Component {
  readonly loader: Loader<ResponseType, RequestParamType>;

  constructor() {
    this.loader = new Loader(param => this.http.get(param));
    this.loader.subscribe(res => {
      // Your stuffs
    }, (error) => { 
      // Error Handling stuffs
    }, () => {
      // on Complete stuffs (Optional)
    });
  }

  ngOnInit() {
    this.loadData();
  }

  loadData() { // Call this function whenever you want to refresh the data
    this.loader.load(params); // this param will directly passed to the http request
  }
}

我在加载器中定义了其他参数,可以帮助你喜欢加载状态和完成流的选项(在ngOnDestroy中)

编码愉快!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 2018-10-15
    • 2019-01-15
    • 2018-10-20
    • 2018-11-02
    • 2018-12-19
    相关资源
    最近更新 更多