如果某些失败无关紧要,如何处理多个可观察对象?

How to handle multiple observables when it doesn't matter if some fails?

我必须在页面启动时订阅多个可观察对象,并且在启动之前我必须等待所有响应。我首先看到的是 forkjoin,但是当一个内部可观察对象抛出错误并且我丢失了其他可观察对象的值时它失败了。

我已经做了类似的东西并且它有效......但我确信有更好的方法:

getResult(){
  let importantObservableResponse1
  let importantObservableResponse2
  let observableResponse3
  let observableResponse4

  return new Observable(obs => {
    this.firstObservable().subscribe(
      response => {
        importantObservableResponse1 = response
        if (importantObservableResponse2, observableResponse3, observableResponse4)
          obs.next([importantObservableResponse1, importantObservableResponse2, observableResponse3, observableResponse4])
      }, error => {
        let error = this.makeError(error)
        obs.error(error)
      }
    )

    this.secondObservable().subscribe(
      response => {
        importantObservableResponse2 = response
        if (importantObservableResponse1, observableResponse3, observableResponse4)
          obs.next([importantObservableResponse1, importantObservableResponse2, observableResponse3, observableResponse4])
      }, error => {
        let error = this.makeError(error)
        obs.error(error)
      }
    )

    this.thirdObservable().subscribe(
      response => {
        observableResponse3 = response
        if (importantObservableResponse1, importantObservableResponse2, observableResponse4)
          obs.next([importantObservableResponse1, importantObservableResponse2, observableResponse3, observableResponse4])
      }, error => {
        observableResponse3 = error
        if (importantObservableResponse1, importantObservableResponse2, observableResponse4)
          obs.next(error)
      }
    )

    this.fourthObservable().subscribe(
      response => {
        observableResponse4 = response
        if (importantObservableResponse1, importantObservableResponse2, observableResponse3)
          obs.next([importantObservableResponse1, importantObservableResponse2, observableResponse3, observableResponse4])
      }, error => {
        observableResponse4 = error
        if (importantObservableResponse1, importantObservableResponse2, observableResponse3)
          obs.next(error)
      }
    )
  })
}

我已将我所有的订阅都放在一个可观察的对象中,当我拥有所有信息时。

有没有办法至少一次获得所有响应,即使有些响应失败?

响应的顺序重要吗?响应可以为空或未定义吗?

如果您只想输出一系列响应,让所有订阅都由同一事物处理,我会亲自重新配置 getResult() 机制。主要是因为我不喜欢那样分层观察,感觉太乱而且难以阅读。

我所说的重新配置的意思是:初始化一个可观察结果并让事物可以订阅,而不是将可观察结果作为 getResult() 方法本身的一部分返回。这允许任意数量的东西订阅它,你可以任意 get/refresh 数据并在它发生时将所述数据推送给所有这些订阅者。

private resultObs: Observer<any[]>;
private resultResponses: any[];

private _result$: Observable<any[]>;

constructor() {
  this._result$ = new Observable<any[]>((x: Observer<any[]>) => { this.resultObs = x; }).pipe(share());
}

public get result$(): Observable<any[]> { return this._result$; }

// Method no longer returns anything, it's merely a triggering method
public getResult(): void {
  this.resultResponses= [];

  this.firstObservable().subscribe(x => this.handleResponse(1, x), err => this.handleError(1, err));

  this.secondObservable().subscribe(x => this.handleResponse(2, x), err => this.handleError(2, err));

  // ...
}


private handleResponse(order: number, response: any): void {
  // If order matters, handle relevant inserting here
  this.resultResponses.push(response);


  // Assuming you only want to emit when all 4 have come in successfully
  if (this.resultResponses.length === 4 && this.resultObs) {
    // Note: the this.resultObs check will ensure you don't get any errors
    // when trying to emit if nothing has subscribed to it yet...
    this.resultObs.next(this.resultResponses);
  }
}

private handleError(order: number, error: any): void {
  // Do whatever you need to do on failures
  console.error(error);
}

以及您拥有的任何使用组件:

public ngOnInit(): void {
  // Subscribe to the result observable
  this.service.result$.subscribe((x: any[]) => this.onResultResponse(x));

  // Trigger the retrieval of the data
  this.service.getResult();
}

private onResultResponse(data: any[]): void {
  // Handle your data now you've got it
  console.log('Got results:', data);
}

编辑:修复了值 emit 的愚蠢错误。