Угловой 4 RxJS опрос с switchMap

1

Недавно я задал вопрос, связанный с утерями подписки, если switchMap обнаружил ошибку:

Угловая 4 проигрывает подписку с маршрутизатором paramMap с помощью switchMap

Решение состояло в том, чтобы вернуть пустое Наблюдаемое, как только Наблюдатель ударит по ошибке, что подписка будет уничтожена.

Теперь мне нужно выяснить, как опросить один и тот же код, но прекратить опрос, как только API вернет данные. Я верю, что возвращение этого пустого Observable приводит к тому, что мой код опроса не работает должным образом.

Текущий код БЕЗ ОПРЕДЕЛЕНИЯ:

ngOnInit() {
  this.subscription = this.route.paramMap
    .switchMap( (params) => {
      this.setChartDefaults();
        return this.getForecastData(params.get('id'))
    .do(null, (err) => {
      this.errorText = err.statusText
      this.loading = false;
    })
    .catch( () => { return Observable.empty() });
  })
}

ngAfterViewInit() {
  this.subscription.subscribe( (data) => {
    // business logic
  }
}

Предлагаемый код С ОПРОСЫ:

ngOnInit() {
  this.subscription = this.route.paramMap
    .switchMap( (params) => {
      return Observable
      .interval(10000)
      .startWith(0)
      .flatMap( () => {
        return this.getForecastData(params.get('id'))
      })
      .filter( (val) => {
        return val.Interval != null
      })
      .take(1)
      .map((forecast) => forecast)
      .do(null, (err) => {
        this.errorText = err.statusText
        this.loading = false;
      })
      .catch( () => { return Observable.empty() });
  })
}

ngAfterViewInit() {
  this.subscription.subscribe( (data) => {
    // business logic
  }
}
  1. switchMap на route.paramMap, что означает, что любые предыдущие Наблюдаемые отменены
  2. return new Observable, который имеет интервал 10 секунд и сразу начинается
  3. flatMap HTTP-запрос и опрос Observables
  4. фильтровать входящие данные, если у него есть свойство Interval, затем взять его и остановить опрос
  5. map возвращает новый наблюдаемый, который необходим для подписки
  6. улов там возвращает пустую наблюдаемую, чтобы справиться с исходной проблемой

Этот код всегда принимает первый результат (с использованием take (1)), однако я понял, что если вы сначала фильтруете, вы можете прагматически принять только первый результат (в моем случае есть действительный ответ).

Это мое текущее, ограниченное понимание и считаю, что в моих знаниях явно имеются пробелы, поэтому я пытаюсь узнать больше о том, как работает цепочка этих операторов и Observables.

  • 2
    Так как это не работает? Или что должен делать этот код? Вы используете take(1) поэтому Observable.interval всегда выдает только один элемент, и тогда цепочка завершена.
  • 0
    Извините, добавил больше деталей к вопросу.
Теги:
angular
rxjs
observable

1 ответ

2
Лучший ответ

Поэтому, после дальнейшего исследования функции RxJS Observables, я обнаружил, что я не должен позволять ошибке "распространяться" по цепочке и эффективно отменить мою подписку. Я также упростил свой код:

public getForecastData(forecastId) : Observable<any> {
  return this.http
    .get<any>('/api/forecasts/' + forecastId)
    .map( res => res)
    .catch( () => Observable.empty());
}

ngOnInit() {
  let $pollObservable = Observable
    .interval(8000)
    .startWith(0);

    this.subscription = this.route.paramMap
      .switchMap( (params) =>
        $pollObservable
        .switchMap( () => {
          this.setChartDefaults();
          return this.getForecastData(params.get('id'))
        })
      .filter( (val) => {
        return val.Interval != null
      })
      .take(1)
      .map( forecast => forecast)
      )
}

ngAfterViewInit() {
  this.subscription.subscribe( (data) => {
    // business logic
  });
}

Я думаю, что я могу поменять второй оператор switchMap на flatMap, но я хочу, чтобы предыдущий (внешний) Observable был отменен.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню