Я пытаюсь использовать RxJS Observables для фильтрации списка объектов на основе выбора пользователей. Чтобы получить список отфильтрованных объектов, мне нужно последовательно вызвать три отдельные службы и передать значения из предыдущей службы в следующую службу.
ПРИМЕЧАНИЕ 1: Каждая из этих трех служб возвращает Observable
ЗАМЕТКА 2: Каждая служба может возвращать произвольное количество результатов, которые необходимо передать следующей службе.
Только после того, как третья служба завершит отправку всех своих значений, мой код может продолжаться нормально.
Вот что у меня есть прямо сейчас:
this.firstService.getFirstResults(filterOption)
.subscribe(firstResult => this.secondService.getSecondResults(firstResult)
.subscribe(secondResult => this.thirdService.getThirdResults(secondResult)
.subscribe(thirdResult => this.processResult(thirdResult, firstResult),
null,
() => console.info("COMPLETE")))
);
Приведенный выше код работает у меня почти идеально. В конце концов, функция processResult() правильно строит массив со всеми отфильтрованными объектами.
Однако я не знаю, как получить уведомление, когда последовательность Observables действительно завершена. Я надеялся, что раздел complete третьей службы выполнит эту работу, но он печатает на консоль несколько раз, а не один раз.
ЗАМЕТКА 3: В последнем вызове processResult() мне нужно передать как значение thirdResult, так и соответствующее значение firstResult, возвращаемое из firstService.getFirstResults().
Извините, параллель - плохой выбор. Думаю, я хотел сказать асинхронно. Только что отредактировал сообщение, чтобы исправить.
Не могли бы вы предоставить фрагмент кода, показывающий, как я могу преобразовать приведенный выше код для использования switchMap или mergeMap? Я пробовал это сам, думая, что это решит мою проблему, но окончательный массив фильтров так и не был построен, и журнал консоли COMPLETE так и не был напечатан. При поиске примера кода в Интернете большинство из них демонстрируют последовательности функций, которые не принимают никаких параметров или не имеют статических параметров.
Спасибо за фрагмент, так как сейчас я, кажется, добился прогресса. Моя единственная оставшаяся проблема, похоже, заключается в том, что я по ошибке поместил переменную filterOption в качестве второго параметра функции processResult(), хотя на самом деле это должно быть значение, возвращаемое firstService, например, переменная processResult (thirdResult, firstResult) . Though with the new code setup, the firstResult не видна после вызова этой функции. Любые идеи?






switchMap предоставил второй параметр для реструктуризации возвращаемого значения, ниже показано, как это сделать.
function getResult(filterOption) {
return this.firstService.getFirstResult(filterOption).pipe(
switchMap(
firstResult => this.secondeService.getSecondResult(firstResult),
([firstResult, secondResult]) => ({ firstResult, secondResult }),
),
switchMap(
({ secondResult }) => this.thirdService.getThirdResult(secondResult),
([{ firstResult }, thirdResult]) => ({ firstResult, thirdResult }),
),
);
}
getResult(filterOption).subscribe({
next: ({ firstResult, thirdResult }) => this.processResult(thirdResult, firstResult),
completed: () => console.info('completed'),
});
Спасибо вам обоим. У меня теперь он правильно работает с оператором mergeMap. Пришлось объединить все это в одну функцию для целей определения объема, поскольку я использую TypeScript, а не JavaScript, но в остальном это, по сути, тот же код выше, который работал у меня.
Используйте оператор switchMap (), mergeMap () или concatMap () (в зависимости от того, что вы действительно хотите). Как они могут работать параллельно, если вам нужно значение, испускаемое первым, для вызова второго?