nestjs 中的 httpSerive 中的 rxjs 用法请教, 在线等

2022-03-17 17:14:24 +08:00
 dengshen

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": "Sincere@april.biz",
    "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": "Shanna@melissa.tv",
    "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

2023 次点击
所在节点    JavaScript
15 条回复
dengshen
2022-03-17 17:28:58 +08:00
怎么移到水了#24 正经提问题呢... @Livid
Livid
2022-03-17 17:29:52 +08:00
@dengshen 标题中有触发自动移动规则的「在线等」
Livid
2022-03-17 17:30:26 +08:00
@dengshen 已经为你手动移动到 /go/js
Oktfolio
2022-03-17 17:32:36 +08:00
dengshen
2022-03-17 17:37:46 +08:00
@Oktfolio #4 这个文档我也看了😭️, 大佬具体指点一下吧
maichael
2022-03-17 17:46:54 +08:00
跟 rxjs 不算很有关系,你这里核心还是异步请求还没返回就已经 return res 回去了,你要考虑怎么 wait 。
wunonglin
2022-03-17 17:57:37 +08:00
dengshen
2022-03-17 17:58:45 +08:00
@maichael #6 现在的代码就是用的 async/await+promise, 但是 nestjs 提供的 httpModule 确实是 rx 化的 axios, 这样的话应该就是跟 rxjs 有关系, 之前没看过 rxjs, 看了示例就干了, 现在撞到墙了, 但是看了文档也没收获到啥.
dengshen
2022-03-17 18:01:53 +08:00
@wunonglin #7 大佬, 我发现有些问题, , id 为偶数的只有 10, 其他的丢了,也看不到有没有 posts 属性
wunonglin
2022-03-17 18:04:10 +08:00
@dengshen #9 好了。刷新下
dengshen
2022-03-17 18:12:24 +08:00
@wunonglin #10 还是不行哦
wunonglin
2022-03-17 18:14:41 +08:00
@dengshen #11 30 行有个 user.post = [];,看不到的话自己在加下就可以了
dengshen
2022-03-17 18:23:49 +08:00
@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(),
);
}),
);
}

```
3825995121
2022-03-18 14:04:46 +08:00
使用 rxjs 里边的 lastValueFrom 转换为 promise 也可以的😁
```javscipt
await lastValueFrom(this.httpService.get('/users'))
```
dengshen
2022-03-18 14:54:43 +08:00
@3825995121 #14 是的, 但是有个老哥推荐全部返回 Observeable 的方式, 我自己也可以学一下, 挑战一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/841063

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX