如何在Nest框架中从Observable类型对象中提取返回数据
问题原因
你遇到的是异步执行时序问题,和subscribe用法无关:
httpService.get返回的Observable发起的是异步HTTP请求,subscribe传入的回调函数仅会在请求拿到响应后才会执行- 你写在
subscribe后的console.log和return属于同步代码,会在请求发出后立刻执行,此时回调还未触发,this.followers自然没有被赋值
解决方案
Nest原生支持在服务/控制器中直接返回Observable类型,框架会自动订阅并解析结果,不需要你手动提取数据落地到变量。以下是两种常用实现方式:
方案1:直接返回Observable(推荐)
使用RxJS的map操作符提取响应中的data字段,直接返回Observable即可,控制器拿到后可直接作为接口返回值:
import { HttpService } from '@nestjs/axios'; import { Injectable } from '@nestjs/common'; import { map, Observable } from 'rxjs'; import { GithubFollower } from './../../../../shared/github.models' @Injectable() export class GithubService { constructor(private httpService: HttpService) {} getFollowers(id: string): Observable<GithubFollower[]> { return this.httpService.get<GithubFollower[]>(`https://api.github.com/users/${id}/followers`) .pipe( map(response => response.data) ); } }
如果需要本地缓存数据到this.followers,可以在pipe里加tap操作符赋值:
import { map, tap, Observable } from 'rxjs'; // 省略其他代码 getFollowers(id: string): Observable<GithubFollower[]> { return this.httpService.get<GithubFollower[]>(`https://api.github.com/users/${id}/followers`) .pipe( map(response => response.data), tap(data => this.followers = data) ); }
方案2:转为Promise使用async/await
如果你习惯同步写法,可以用RxJS提供的firstValueFrom将Observable转为Promise,配合async/await取值:
import { HttpService } from '@nestjs/axios'; import { Injectable } from '@nestjs/common'; import { firstValueFrom } from 'rxjs'; import { GithubFollower } from './../../../../shared/github.models' @Injectable() export class GithubService { private followers: GithubFollower[] constructor(private httpService: HttpService) {} async getFollowers(id: string): Promise<GithubFollower[]> { const response = await firstValueFrom( this.httpService.get<GithubFollower[]>(`https://api.github.com/users/${id}/followers`) ); this.followers = response.data; return this.followers; } }
注意:不建议将请求结果存到类的私有属性
this.followers中,高并发场景下多个请求会互相覆盖属性值,除非你明确需要做全局缓存逻辑。
内容的提问来源于stack exchange,提问作者Rayder-_-
相关产品推荐
相关产品推荐

