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

发布于 2025-01-12 11:23:09 字数 1277 浏览 1 评论 0原文

我正在开发的应用程序使用 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) })))
        );
      })
   )
);

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

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

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

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

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

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

The application I am working on uses a NgRx Store, and I am triggering my API calls via @ngrx/effects.
I think my problem can be best explained by imagining a simple to-do list.
The following is a simplification of the current state of one of my effects.

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) })))
        );
      })
   )
);

When the user checks an item from the list and instantly unchecks it again (because they f.e. made a mistake) now two parallel requests are on their way.
Since the backend wants to prevent multiple users from overwriting other changes, versioning is applied.
Due to this the second request will fail, because it still contains the old version number.

enter image description here

So for this to work the client has to wait for the request to finish and afterwards send the second request.

The problem with sending only one request at a time is, that this would also apply if two seperate list items are edited, which should be possible to reduce unnecessary waiting time.

So to summarize my wanted behaviour would be to only wait if there already is a pending request for the same list item.
Otherwise, the client should just send the request.

Edit: This is the html template for the list.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静谧 2025-01-19 11:23:09

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

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

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

You can achieve this by combining some RxJS operators.
The main one being groupBy, where you'll split the stream into multiple groups - in your case this will be a todo item. Within each group you can use concatMap to send the requests in order.

For more info and a demo, see the following talk by Mike Ryan and Sam Julien.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文