Как разместить несколько запросов POST в Angular одновременно? - PullRequest
0 голосов
/ 07 марта 2020

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

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

ПРИМЕР

У меня есть такой массив

const planningChannels=[
{icon: "libraryBooks", name: "Blogs", type: "custom", color: "#dc4e41", purpose: "planning"},
{icon: "instagram", name: "instagram DM", type: "custom", color: "#50e3c2", purpose: "planning"},
{icon: "pinterest", name: "pinterest", type: "custom", color: "#535353", purpose: "planning"}
]

, и я перебираю массив с forEach l oop:

planningChannels.forEach(channel => {
    this.calendarService.createChannel(calendarId, channel)
      .subscribe(
        createdChannel => {},
        error => this.notificationsService.apiError(error),
      );
});

Функция calendarService.createChannel выглядит следующим образом:

createChannel(calendarId: string,channel: Partial<IChannel>): Observable<IChannel> {
    const requestUrl = `/calendar/${calendarId}/channel/`;

    return this.http.post<IChannel>(requestUrl, channel).pipe(
      tap(createdChannel => {
        this.stateManager.dispatch(
          {
            id: calendarId,
            channels: [createdChannel],
          } as ICalendarUpdatedEntities,
          CalendarEntitiesFetched
        );
      })
    );
  }

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

Ответы [ 3 ]

1 голос
/ 07 марта 2020

Не думаю, что могу ответить, почему не все 3 видны на передней панели. Но я могу предложить более оптимальный способ выполнения ваших http-запросов, используя «merge» или «concat». При «слиянии» все ваши http-запросы будут запущены одновременно. С помощью «concat» http-запросы будут помещаться в очередь, и каждый из них будет go после завершения предыдущего.

Вместо вашего forEach l oop вы можете сделать следующее:

const pcObservables = planningChannels.map(channel => this.calendarService.createChannel(calendarId, channel));
concat(...pcObservables).subscribe(
  createdChannel => {},
  error => this.notificationsService.apiError(error),
);
0 голосов
/ 07 марта 2020

Если вы имеете в виду, что после выполнения 3 POSTS во внешнем интерфейсе отображается только один результат, это может быть связано с

channels: [createdChannel],

, который представляет собой только один ответ в массиве, но не все 3 ответа. Я бы предложил использовать forkJoin или что-то подобное, потому что у вас будут все 3 ответа в одном месте, которые вы сможете легко вывести в состояние sh.

0 голосов
/ 07 марта 2020

Вы можете запустить несколько наблюдаемых параллельно, используя forkJoin.

Во-первых, настройте свои наблюдаемые:

const planningChannels=[
  {icon: "libraryBooks", name: "Blogs", type: "custom", color: "#dc4e41", purpose: "planning"},
  {icon: "instagram", name: "instagram DM", type: "custom", color: "#50e3c2", purpose: "planning"},
  {icon: "pinterest", name: "pinterest", type: "custom", color: "#535353", purpose: "planning"}
];

const observables = planningChannels.map(channel =>   
  this.calendarService.createChannel(calendarId, payload).pipe(
    catchError(error => {
      this.notificationsService.apiError(error);
      return of(null);
    })
  )
);

Эти наблюдаемые не выполняются, пока что-то на них не подпишется. Обратите внимание, как каждая наблюдаемая может обрабатывать ошибки в своем собственном канале.

Теперь вы можете использовать forkJoin для запуска их как одной наблюдаемой.

forkJoin(observables).subscribe(createdChannels => {
  const state = {
    id: calendarId,
    channels: createdChannels,
  } as ICalendarUpdatedEntities;

  this.stateManager.dispatch(state,  CalendarEntitiesFetched);
});

Я предположил, что вы хотите, чтобы все наблюдаемые беги, даже если не получится. Значение, возвращаемое из forkJoin, будет массивом той же длины, что и входной массив. Он будет содержать либо объекты, возвращенные из службы, либо null, возвращенные из catchError. Возможно, имеет смысл перенести обработку ошибок в вашу службу, но я хотел, чтобы мой пример был как можно ближе к вашему оригиналу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...