如何在 Angular 中同时 post 多个 POST 请求?

How do I post multiple POST requests in Angular at the same time?

我正在处理需要使用 HTTP post 请求的工作,但它需要是动态的,因为要发出的 post 请求的数量可能会有所不同。

我有一个对象数组,我想 post 每个对象到 httpClient 但到目前为止它只成功地 posted 数组的最终对象。

示例

我有一个这样的数组

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 循环遍历数组:

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 个网络请求,但只有一个在我的前端可见。谁能帮我解决我哪里出错了?

您可以 运行 使用 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);
    })
  )
);

这些 observables 在订阅它们之前不会执行。请注意每个可观察对象如何处理其自身管道中的错误。

现在您可以使用 forkJoin 到 运行 它们作为一个可观察对象。

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

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

我假设您希望所有可观察对象 运行 即使一个失败。从 forkJoin 返回的值将是一个与输入数组长度相同的数组。它将包含从服务返回的对象,或从 catchError 返回的 null。将错误处理移到您的服务中可能是有意义的,但我想让我的示例尽可能接近您的原始示例。

我想我无法回答为什么不是所有 3 个都在前端可见。但我可以通过使用 "merge" 或 "concat" 建议一种更优化的方式来执行您的 http 请求。使用 "merge",您所有的 http 请求将同时触发。使用 "concat" 时,http 请求将排队,每个请求都将在前一个完成后进行。

您可以执行以下操作来代替您的 forEach 循环:

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

如果你的意思是执行3个POST后前端只看到一个结果,可能是因为

channels: [createdChannel],

这只是数组中的一个响应,而不是所有 3 个响应。 我建议使用 forkJoin 或类似的东西,因为你将在一个地方拥有所有 3 个响应,你将能够轻松地将其推送到状态。