Angular ожидает завершения нескольких наблюдаемых

Я новичок в Angular, не говоря уже о реактивном программировании, и мне трудно с головой окунуться в библиотеки и понять, как все должно работать вместе.

По этому поводу уже есть несколько вопросов о переполнении стека, но ни один из них, который я вижу, не касается ситуации, с которой я здесь имею дело.

У меня есть два списка объектов Observables. var obsrv1 = Observable<Object1[]>, var obsrv2 = Observable<Object2[]>.

Допустим, у меня есть вся базовая логика для вызовов API и прочего, и обычно, когда я делаю что-то вроде obsrv1.subscribe(results => this.objectArray = results), он будет делать это асинхронно и в конечном итоге получит мои данные.

Теперь у меня проблема с двумя моими наблюдаемыми, и это то, что одна из них зависит от другого списка. Когда два списка данных завершены, мне нужно выполнить действие, чтобы объединить их в объект другого типа.

Одно из решений - просто сделать что-то вроде этого:

obsrv1.subscribe(
  obsrv1Results => {
  this.object1Array = obsrv1Results
  },
  err => {},
  () => {
    obsrv2.subscribe(
      obsrv2Results => {
        this.object2Array = obsrv2Results
      },
      err => {},
      () => onDataLoadComplete();
    );
  }
);

Это работает, но кажется очень хакерским. Я понял, что есть гораздо более элегантный способ сделать это, и похоже, что люди предлагают что-то сделать с forkJoin, но я понятия не имею, как заставить его работать. Похоже, они предлагают сделать forkJoin([obsrv1, obsrv2]).subscribe(...), но выполнение этого с моим кодом не дает результатов, и обратный вызов подписки никогда не вызывается. Некоторые люди говорят, что нужно делать, forkJoin([obsrv1.first(), obsrv2.first()]), но это тоже не работает, и единственные результаты, которые я получаю, это буквально ,, когда я создаю console.info.

Как бы то ни было, в моем приложении я использую ngrx / store и ngrx / effects. Вызов для получения моих данных выглядит так:

this.store.select(state => state.myDataContainer.dataList), который возвращает Store<MyDataType[]>. Из того, что я собрал, объекты Store<T> должны быть наблюдаемыми в той или иной форме, потому что вы можете подписаться на них.

Как я могу получить оба моих набора данных асинхронно и запустить обратный вызов, когда оба набора данных завершены?

Если вы собираетесь проголосовать против меня, по крайней мере, скажите, почему я идиот, вместо того, чтобы намекать на это. Возможно, Stack Overflow будет менее опасен для людей, пытающихся учиться.

Zulukas 23.04.2018 22:34

Я полагаю, что голос "против" принадлежит кому-то, кто считает, что этот вопрос задавали 100 раз на SO; мне даже так кажется. Просить объяснений у проигравшего голосующего - почти пустая трата времени. Как выглядит ваша служба передачи данных? Думаю, именно здесь вы и хотите сделать forkJoin. Этот может быть полезным.

R. Richards 23.04.2018 22:59
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
2
1 101
1

Ответы 1

Похоже, вам следует использовать оператор .pipe(flatMap()). Вы можете использовать это, чтобы использовать результат одного Observable и вернуть другой Observable, что вы описываете, что хотите сделать.

Сайт ReactiveX.io довольно хорошо визуализирует и объясняет эти вещи.

Вот пример, который работает "из коробки":

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { flatMap } from 'rxjs/operators';

//emit 1
const source = Observable.of(1);
//do something with value
const example = source.pipe(flatMap(value => {return Observable.of(value + 10)}));
//output: 11,12,13,14,15
const subscribe = example.subscribe(val => console.info(val));

И вот как может выглядеть ваш код, реализующий это:

obsrv1.pipe(
  flatMap(obsrv1Results => {
    this.object1Array = obsrv1Results;
    return obsrv2;
  })
).subscribe(obsrv2Results => {
  this.object2Array = obsrv2Results;
  onDataLoadComplete();
});

Не забудьте импортировать flatMap, если он вам нужен:

import { flatMap } from "rxjs/operators";

Удачи!

Другие вопросы по теме