rxjs 新手上路, 在使用 nestjs 中用到了 HttpModule, 是基于 rxjs 封装的一个 axios, 在用的过程中不熟悉 rxjs 的用法, 官网来来回回看了好久了, 不得方法 结果达不到预期, 请教一下大佬正确的姿势. 谢谢
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [
HttpModule.register({
baseURL: 'https://jsonplaceholder.typicode.com',
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
// controller
@Get('/')
getHello() {
return this.appService.getHello();
}
// service
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { map } from 'rxjs';
@Injectable()
export class AppService {
constructor(private httpService: HttpService) {}
getHello() {
return this.httpService.get('/users').pipe(
map((res) => res.data),
map((data) => {
return data.map((user) => {
user.name = user.name.toUpperCase();
user.posts = [];
if (user.id % 2 === 0) {
// 当符合条件时,需要获取到对应的 posts 并 push 给当前的 user
this.httpService.get('/posts/' + user.id).pipe(
map((post) => {
user.posts.push(post.data);
}),
);
}
return user;
});
}),
map((res) => {
return res;
}),
);
}
}
[
{
"id": 1,
"name": "LEANNE GRAHAM",
"username": "Bret",
"email": "[email protected]",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": { "lat": "-37.3159", "lng": "81.1496" }
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
},
"posts": []
},
{
"id": 2,
"name": "ERVIN HOWELL",
"username": "Antonette",
"email": "[email protected]",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": { "lat": "-43.9509", "lng": "-34.4618" }
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
},
"posts": ['postObject1']
}
]
"dependencies": {
"@nestjs/axios": "^0.0.7",
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0",
"axios": "^0.26.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
},
这里写了一个基于 promise 实现需求的例子, 希望大佬提供一个切换成 rxjs 实现的例子 点击这里 codePen
4
Oktfolio 2022-03-17 17:32:36 +08:00
|
6
maichael 2022-03-17 17:46:54 +08:00
跟 rxjs 不算很有关系,你这里核心还是异步请求还没返回就已经 return res 回去了,你要考虑怎么 wait 。
|
7
wunonglin 2022-03-17 17:57:37 +08:00
|
8
dengshen OP @maichael #6 现在的代码就是用的 async/await+promise, 但是 nestjs 提供的 httpModule 确实是 rx 化的 axios, 这样的话应该就是跟 rxjs 有关系, 之前没看过 rxjs, 看了示例就干了, 现在撞到墙了, 但是看了文档也没收获到啥.
|
9
dengshen OP @wunonglin #7 大佬, 我发现有些问题, , id 为偶数的只有 10, 其他的丢了,也看不到有没有 posts 属性
|
13
dengshen OP @wunonglin #12 照葫芦画瓢可以了, 谢谢大佬, 我这里用的是 mergeMap
``` getTest() { return this.httpService.get('/users').pipe( map((res) => res.data), switchMap((users) => { if (!Array.isArray(users)) { return of([]); } return from(users).pipe( mergeMap((user: any) => { user.posts = []; if (user.id % 2 === 0) { return this.httpService.get('/posts/' + user.id).pipe( map((posts) => { user.posts.push(posts.data); return user; }), ); } else { return of(user); } }), toArray(), ); }), ); } ``` |
14
3825995121 2022-03-18 14:04:46 +08:00
使用 rxjs 里边的 lastValueFrom 转换为 promise 也可以的😁
```javscipt await lastValueFrom(this.httpService.get('/users')) ``` |
15
dengshen OP @3825995121 #14 是的, 但是有个老哥推荐全部返回 Observeable 的方式, 我自己也可以学一下, 挑战一下
|