Как обрабатывать несколько наблюдаемых, когда неважно, что некоторые из них не работают?

Мне нужно подписаться на несколько наблюдаемых при запуске страницы, и мне нужно дождаться всех ответов перед запуском. Первое, что я увидел, это 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)
      }
    )
  })
}

Я поместил всю свою подписку в наблюдаемое, и когда у меня есть вся информация.

Есть ли способ хотя бы получить все ответы сразу, даже если некоторые из них не работают?

См. также:  Cypress - Ошибка: не удается найти модуль '../../webpack.config.js'
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 1
  1. Brett

    Имеет ли значение порядок ответа? Могут ли ответы быть нулевыми или неопределенными?

    Если все, что вы хотите сделать, это выдать массив ответов, сделать так, чтобы все подписки обрабатывались одним и тем же способом, и я бы лично перенастроил механизм getResult(). В основном из-за того, что я не поклонник подобного расслоения наблюдаемых, это кажется слишком беспорядочным и трудным для чтения.

    Что я имею в виду под перенастройкой: иметь наблюдаемый результат, инициализированный и сидящий без дела, на который вещи могут подписаться, а не возвращать наблюдаемое как часть самого метода getResult(). Это позволяет любому количеству вещей подписаться на него, и вы можете произвольно получать / обновлять данные и отправлять указанные данные всем этим подписчикам, когда это происходит.

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

    Изменить: исправлена ​​глупая ошибка со значением испускания.

    Большое тебе спасибо! это то, что я искал !!! Я пытаюсь реализовать это, и у меня проблема со строкой this.result $ .next (this.resultResponses); на ручке Ответ. Он говорит, что свойство ‘next’ не существует для типа ‘Observable ‹any []›’. person Brett; 02.12.2020

    Ах, моя ошибка — это не наблюдаемое (result$) излучает (next()), а наблюдатель (resultObs). Замените это, и он должен работать нормально. person Brett; 03.12.2020

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: