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





Похоже, вам следует использовать оператор .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";
Удачи!
Если вы собираетесь проголосовать против меня, по крайней мере, скажите, почему я идиот, вместо того, чтобы намекать на это. Возможно, Stack Overflow будет менее опасен для людей, пытающихся учиться.