如何为数组的所有元素依次调用 API 函数?

csa*_*nsz 1 javascript rxjs angular

我正在使用 RxJs 与 Angular 合作,目前发现解决这个问题非常具有挑战性。

我有一个包含一些 id 的数组。

ids = [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

然后我有一个可以使用 id 参数调用的 API,它从数据库中删除具有给定 id 的项目:

this.controller.deleteItem(id)
Run Code Online (Sandbox Code Playgroud)

我想对数组中的每个 id 调用此 API。

这些 API 调用应该严格按照顺序模式依次发生,例如

this.controller.deleteItem(1) -> this.controller.deleteItem(2) 等

所有 api 调用完成后,我想通过以下方式获取数据:

this.controller.getData()
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

Oct*_*scu 5

您可以使用concat运算符来完成此操作。

首先,您需要通过将数组的每个项目映射到其相应的删除操作,将 ID 列表转换为可观察列表:

const idsToDelete = [1, 2, 3];
const deleteTasks = idsToDelete.map(id => this.controller.deleteItem(id));
Run Code Online (Sandbox Code Playgroud)

然后使用concat顺序执行任务:

concat(...deleteTasks).subscribe((response) => {
  console.log('deleted', response);
});
Run Code Online (Sandbox Code Playgroud)

为了在末尾获取数据(假设该getData方法也返回一个可观察值),您可以将其插入到末尾、删除之后,并且只监听响应last

concat(...deleteTasks, this.controller.getData()).pipe(
  // tap((res) => console.log(res)),
  last()
).subscribe((dataAfterDelete) => {
  console.log(dataAfterDelete);
});
Run Code Online (Sandbox Code Playgroud)

如果您想有机会使用switchMap运算符在删除操作和数据获取之间执行副作用,您还可以拆分这些调用:

const sequentialDelete = concat(...deleteTasks);
sequentialDelete.pipe(
  tap((deleteItemResponse) => {
    console.log('after each item delete', deleteItemResponse);
  }),
  last(),
  tap(() => {
    console.log('after the last item was deleted');
    this.idsToDelete = [];
  }),
  switchMap(() => this.controller.getData())
).subscribe((dataAfterDelete) => {
  console.log(dataAfterDelete);
});
Run Code Online (Sandbox Code Playgroud)