Вызов наблюдаемых синхронно один за другим в Angular

У меня доступны следующие сервисные вызовы:
productService.GetAllProducts ()
productService.DeleteProduct ()
productService.GetCategories ()
productService.DeleteCategory ()

В коде sudo мне нужно сделать следующее в моем компоненте:

  1. Получите список продуктов с помощью productService.GetAllProducts ().

  2. Прокрутите список продуктов и вызовите productService.DeleteProduct () для каждого продукта.

  3. Как только я смогу подтвердить, что все вышеупомянутые удаления завершены (из-за ограничений базы данных), мне нужно затем получить список категорий с помощью productService.GetCategories (). Прокрутите каждую категорию и вызовите productService.DeleteCategory ().

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

Возможно ли вообще то, что я пытаюсь сделать, используя flatMap и наблюдаемый полный параметр? Моя самая большая проблема - это знать, когда код завершает удаление всех продуктов, прежде чем искать и удалять все категории.

Вы уже задавали такой же вопрос: stackoverflow.com/questions/51047390/…. И вы получили ответ и несколько ссылок.

JB Nizet 26.06.2018 19:50

Ссылки в этом посте не решают мою проблему. Вы действительно читаете то, что я пытаюсь сделать, или просто сразу помечаете вещи как дубликаты на основе заголовка? Я понял, что моя проблема немного отличается от сообщения, на которое вы указали ссылку, поэтому создал новое сообщение.

Blake Rivell 26.06.2018 19:56

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

JB Nizet 26.06.2018 19:58

Понятно, я изучу их более внимательно. В любом случае, вы можете просто дать мне общее представление, глядя на мои 4 шага кода sudo выше того, какие функции мне понадобятся для каждой части?

Blake Rivell 26.06.2018 20:01

Сделайте одну наблюдаемую из нескольких, которые должны выполняться параллельно (то есть множество удалений), используя forkJoin. Используйте switchMap для выполнения одного наблюдаемого объекта за другим.

JB Nizet 26.06.2018 20:02

Спасибо, это должно привести меня на правильный путь. Прошу прощения, я не осознавал, что наблюдаемые настолько сложны. Я так привык писать такой код синхронно на C#, просто выполняя прямые вызовы репозиториев.

Blake Rivell 26.06.2018 20:06

@JBNizet, это нет, что делает switchMap!

cwharris 26.06.2018 21:41

@BJNizet По крайней мере, это неполное вводящее в заблуждение описание switchMap. switchMap поддерживает только одну внутреннюю подписку и отменит все подписки, кроме последней, если подписка еще не завершена. concat подписывается на одну наблюдаемую после завершения другой. switchMap подписывается, как только становится доступным следующее наблюдаемое, и немедленно освобождает свою подписку на предыдущее наблюдаемое.

cwharris 26.06.2018 21:44
Тестирование функциональных 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
8
6 464
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать что-то в этом роде

productService.GetAllProducts()
.switchMap(
   products => forkJoin(products.map(product => productService.DeleteProduct(product)))
)
.switchMap(() => productService.GetCategories())
.switchMap(
   categories => forkJoin(categories.map(category => productService.DeleteCategory(category)))
)
.subscribe(() => console.info('done'))

Вся идея в следующем

  • GetAllProducts возвращает массив продуктов, который передается как параметр к первому switchMap
  • Массив Products преобразуется через map в массив Наблюдаемые объекты, являющиеся результатом DeleteProduct - массива Observable передается первому forkJoin в качестве параметра
  • forkJoin излучает, когда все наблюдаемые объекты, полученные как параметр завершен, и, следовательно, будет выдан, когда все продукты были удалены
  • То же самое рассуждение повторяется для категорий

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

спасибо за отличный ответ. На самом деле я решил разрешить это аналогичным образом, все еще используя forkJoin и map для удалений, поэтому они происходят параллельно, но установил каждый из наблюдаемых удалений в переменную, а затем использовал concat и подписался на него. Примерно так ... Подпишитесь на GetAllProducts, а затем создайте в нем const deleteProducts, который выполняет forkJoin и map. Затем подписался на GetCategories, а затем внутри нее создайте константу deleteCategories, которая выполняет forkJoin и map. Затем, наконец, const deletes = concat (deleteProducts, deleteCategories) .subscribe ().

Blake Rivell 27.06.2018 20:43

дайте мне знать, если вы считаете, что техника switchMap лучше по какой-либо причине.

Blake Rivell 27.06.2018 20:44

Я не уверен, что понимаю логику, но на первый взгляд у меня возникает вопрос, как вы уверены, что deletes = concat(deleteProducts, deleteCategories).subscribe() работает с deleteProducts, а deleteCategories на самом деле являются переменными, указывающими на результат 2 forkJoin, и они все еще не undefined. Подход, который я предлагаю, представляет собой цепочку операторов, которые шаг за шагом преобразуют первый "исходный" Observable в другие Observable, пока вы не получите последний объект, на который вы подписались, чтобы выполнить работу. Вообще я склонен думать, что чем меньше у вас subscribe, тем он лучше.

Picci 27.06.2018 22:00

С помощью цепочки я предлагаю вам всегда знать, что вы делаете, и каким-то образом вы можете вернуть контроль над потоками асинхронных событий, таких как те, которые вы описываете.

Picci 27.06.2018 22:02

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