如何在使用 @ngrx/effects 进行 API 调用时处理更改

How to handle changes while an API call is still in progress with @ngrx/effects

我正在处理的应用程序使用 NgRx Store,我正在通过@ngrx/effects 触发我的 API 调用。 我认为可以通过想象一个简单的待办事项列表来最好地解释我的问题。 以下是我的一个效果的当前状态的简化。

persistItem$ = createEffect(() =>
   this.actions$.pipe(
      ofType(ListActions.ActionType.PersistItem),
      mergeMap(({ listItem }) => {
        return this.listApiService.modifyListItem(listItem).pipe(
          map((updatedItem) => ListApiActions.persistItemSuccess({ updatedItem })),
          catchError((error) => of(ListApiActions.persistItemFailure({ failedItem: mergeItemWithError(listItem, error) })))
        );
      })
   )
);

当用户从列表中选中一个项目并立即再次取消选中它(因为他们 f.e。犯了一个错误)现在有两个并行请求在路上。 由于后端要防止多个用户覆盖其他更改,因此应用了版本控制。 因此,第二个请求将失败,因为它仍然包含旧版本号。

因此,为了使其正常工作,客户端必须等待请求完成,然后再发送第二个请求。

一次只发送一个请求的问题是,如果编辑两个单独的列表项,这也适用,这应该可以减少不必要的等待时间。

因此,总结一下我想要的行为就是仅在已经存在对同一列表项的未决请求时才等待。 否则,客户端应该只发送请求。

编辑:这是列表的 html 模板。

<ul>
  <li *ngFor="let item of listItems$ | ngrxPush">
     {{ item.text }} <button (click)="toggleDone(item)">{{ item.done ? 'Undo' : 'Done' }}</button>
   </li>
</ul>

您可以通过组合一些 RxJS 运算符来实现这一点。 主要的是 groupBy,您将在其中将流分成多个组 - 在您的情况下,这将是一个待办事项。在每个组中,您可以使用 concatMap 按顺序发送请求。

有关详细信息和演示,请参阅 Mike Ryan 和 Sam Julien 的以下演讲。

https://www.youtube.com/watch?v=hsr4ArAsOL4