V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
dengshen
V2EX  ›  JavaScript

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

  •  
  •   dengshen · 2022-03-17 17:14:24 +08:00 · 2188 次点击
    这是一个创建于 983 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 为奇数时 posts 应该为空, id 为偶数时 posts 应该有获取到的 post
    [
      {
        "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']
      }
    ]
    
    

    现状

    • 所有 user 的 posts 都为空

    版本环境

      "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

    15 条回复    2022-03-18 14:54:43 +08:00
    dengshen
        1
    dengshen  
    OP
       2022-03-17 17:28:58 +08:00
    怎么移到水了#24 正经提问题呢... @Livid
    Livid
        2
    Livid  
    MOD
       2022-03-17 17:29:52 +08:00
    @dengshen 标题中有触发自动移动规则的「在线等」
    Livid
        3
    Livid  
    MOD
       2022-03-17 17:30:26 +08:00
    @dengshen 已经为你手动移动到 /go/js
    Oktfolio
        4
    Oktfolio  
       2022-03-17 17:32:36 +08:00
    dengshen
        5
    dengshen  
    OP
       2022-03-17 17:37:46 +08:00
    @Oktfolio #4 这个文档我也看了😭️, 大佬具体指点一下吧
    maichael
        6
    maichael  
       2022-03-17 17:46:54 +08:00
    跟 rxjs 不算很有关系,你这里核心还是异步请求还没返回就已经 return res 回去了,你要考虑怎么 wait 。
    wunonglin
        7
    wunonglin  
       2022-03-17 17:57:37 +08:00
    dengshen
        8
    dengshen  
    OP
       2022-03-17 17:58:45 +08:00
    @maichael #6 现在的代码就是用的 async/await+promise, 但是 nestjs 提供的 httpModule 确实是 rx 化的 axios, 这样的话应该就是跟 rxjs 有关系, 之前没看过 rxjs, 看了示例就干了, 现在撞到墙了, 但是看了文档也没收获到啥.
    dengshen
        9
    dengshen  
    OP
       2022-03-17 18:01:53 +08:00
    @wunonglin #7 大佬, 我发现有些问题, , id 为偶数的只有 10, 其他的丢了,也看不到有没有 posts 属性
    wunonglin
        10
    wunonglin  
       2022-03-17 18:04:10 +08:00
    @dengshen #9 好了。刷新下
    dengshen
        11
    dengshen  
    OP
       2022-03-17 18:12:24 +08:00
    @wunonglin #10 还是不行哦
    wunonglin
        12
    wunonglin  
       2022-03-17 18:14:41 +08:00
    @dengshen #11 30 行有个 user.post = [];,看不到的话自己在加下就可以了
    dengshen
        13
    dengshen  
    OP
       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
        14
    3825995121  
       2022-03-18 14:04:46 +08:00
    使用 rxjs 里边的 lastValueFrom 转换为 promise 也可以的😁
    ```javscipt
    await lastValueFrom(this.httpService.get('/users'))
    ```
    dengshen
        15
    dengshen  
    OP
       2022-03-18 14:54:43 +08:00
    @3825995121 #14 是的, 但是有个老哥推荐全部返回 Observeable 的方式, 我自己也可以学一下, 挑战一下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2729 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:36 · PVG 08:36 · LAX 16:36 · JFK 19:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.