根据 id 连接两个可观察对象

Joining two observables based on id

我有两个 api 调用,一个用于获取所有类别,另一个用于获取 post。在 posts api 中,我正在获取类别 ID,我只需要调用类别并获取类别名称并在 post 调用中添加名称而不是 ID。我知道不建议使用嵌套 api 调用,所以我使用了 flatMap 但不知道如何实现它。

类别

[
  {
    "id": 5,
    "name": "Angular",
    "slug": "angular",
    "parent": 4
  },
  {
    "id": 4,
    "name": "Tutorial",
    "slug": "tutorial",
    "parent": 0
  }
]

posts

[
  {
    "id": 1,
    "categories": [
      5,
      4
    ]
  },
  {
    "id": 2,
    "categories": [
      5
    ]
  }
]

代码

this.blogService.getCategories()
  .pipe(
  flatMap((categories: BlogCategoryModel[]) => {
    console.log(JSON.stringify(categories)); // I think I have to do logic here
    return this.blogService.getPosts();
  })
).subscribe(posts => console.log(JSON.stringify(posts)));

预期结果

[
  {
    "id": 1,
    "categories": [
      "Angular",
      "Tutorial"
    ]
  },
  {
    "id": 2,
    "categories": [
      "Angular"
    ]
  }
]

您可以使用mergeMap

这样试试:

var result = this.blogService.getCategories().pipe(
  mergeMap(value =>  this.getPosts(value[0].id)))
);

Observable 可以提供大量的方法和工具来创建美观且可读的管道。这是一个例子:

// my.service.ts
getData1(): Observable {
  return this.httpClient.get();
}

getData2(): Observable {
  return this.httpClient.post();
}

getData3(): Observable {
  return this.httpClient.get();
}
my.component.ts

ngOnInit() {
  this.myService.getData1().pipe(
    map(data => {
      // do what you want with the request answer
      data.id += 1;
      return data;
    }),
    // Pass the modified data and return the Observable for the getData2 request
    switchMap(data => this.myService.getData2(data)),
    // RxJs have a ton of feature to let you play with the data and the pipeline
    // This will wait for 2000ms
    delay(2000),
    // Pass the data returns by getData2 requests to the method getData3
    switchMap(data => this.myService.getData3(data)),
  ).subscribe(
    data => console.log(data); // The result of your pipeline
  )
}

这里发生了什么:

  1. getData1() 被调用并将 return 我们的 HttpRequest
  2. 的 Observable
  3. 我们修改之前请求的结果(增加id)
  4. 我们使用修改后的结果来调用 getData2,它 return 是请求的 Observable
  5. 我们等待 2000 毫秒以继续
  6. 我们使用getData2请求的结果调用getData3
  7. 我们订阅此管道以获取最终结果

If you do not subscribe to a pipeline, it will never be triggered

RxJs 是一个非常庞大且不错的数据库,但是太多人不知道如何用好它。

要使用该库,您只需遵循一件事:

  • 永远不要将 Observable 放入 Observable 中

关于链接Rxjs,因为这是一个经常被问到的问题,你可以参考一些以前在SO上问过的问题,其中:

  • How to do the chain sequence in rxjs

您可以只使用 forkJoin 而不用 mergeMap/flatMap:

forkJoin([
  this.blogService.getCategories(),
  this.blogService.getPosts(),
]).pipe(
  map(([categories, posts]) => {
    posts.forEach(post => {
      // Replace category ids with their names from `categories` array
    });
    return posts;
  })
).subscribe(posts => ...);