
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 shakaraka PRO |
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 的方式, 我自己也可以学一下, 挑战一下 |