根据 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
)
}
这里发生了什么:
- getData1() 被调用并将 return 我们的 HttpRequest
的 Observable
- 我们修改之前请求的结果(增加id)
- 我们使用修改后的结果来调用 getData2,它 return 是请求的 Observable
- 我们等待 2000 毫秒以继续
- 我们使用getData2请求的结果调用getData3
- 我们订阅此管道以获取最终结果
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 => ...);
我有两个 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
)
}
这里发生了什么:
- getData1() 被调用并将 return 我们的 HttpRequest 的 Observable
- 我们修改之前请求的结果(增加id)
- 我们使用修改后的结果来调用 getData2,它 return 是请求的 Observable
- 我们等待 2000 毫秒以继续
- 我们使用getData2请求的结果调用getData3
- 我们订阅此管道以获取最终结果
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 => ...);