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

时间:2020-03-07 11:03:31

标签: angular typescript http-post observable angular-httpclient

我正在处理需要使用HTTP post请求的工作,但是它必须是动态的,因为要发出的发布请求的数量可以变化。

我有一个对象数组,我想将每个对象发布到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循环遍历数组:

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 个答案:

答案 0 :(得分:0)

您可以使用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。将错误处理转移到您的服务中可能很有意义,但是我想让示例尽可能地接近您的原始示例。

答案 1 :(得分:0)

我想我不能回答为什么不是所有3个都在前端可见。但是我可以建议使用“合并”或“ concat”来执行您的http请求的一种更优化的方法。使用“合并”,您的所有HTTP请求将同时触发。使用“ concat”,http请求将被查询,并且每个请求都将在前一个请求完成之后进行。

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

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

答案 2 :(得分:0)

如果您表示执行3个POST后在前端仅显示一个结果,则可能是由于

channels: [createdChannel],

这只是数组中的一个响应,但不是全部3个响应。 我建议使用forkJoin或类似的方法,因为您将所有3个响应都放在一个位置,可以轻松将其推到状态。