Angular服务内订阅Http请求无响应 组件内订阅正常问题求助
问题根因
你遇到的问题本质是对RxJS异步Observable的执行逻辑理解偏差,不存在配置遗漏:HttpClient.get返回的是冷Observable,订阅后才会发起异步HTTP请求,请求过程不会阻塞后续代码执行。你当前在服务的getInHomeList方法中,刚发起订阅就立刻返回this.result和this.error,此时HTTP请求还未完成,这两个变量还处于未赋值的初始状态,组件拿到的是空值,自然不会有任何响应。而你直接在组件内订阅的写法是请求完成后才给组件变量赋值,所以可以正常运行。
修复方案
Angular 服务封装HTTP请求的最佳实践是服务仅返回Observable实例,订阅逻辑放在组件侧,修改代码如下:
修改ApiService代码
import { Injectable} from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Food } from './api-models'; import { catchError, throwError } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ApiService { constructor( private http: HttpClient) {} // 直接返回Observable,不在服务内部做订阅 getInHomeList() { return this.http.get<Food[]>('https://localhost:5001/').pipe( catchError(this.handleError) ); } handleError(error: any) { let errorMessage = ""; if (error.error instanceof ErrorEvent) { // 客户端侧错误 errorMessage = `Error: ${error.error.message}`; } else { // 服务端侧错误 errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`; } console.log(errorMessage); return throwError(() => new Error(errorMessage)) } }
修改组件代码
import { Component, OnInit } from '@angular/core'; import { Food } from '../api/api-models'; import { ApiService } from '../api/api.service'; @Component({ selector: 'app-in-home-list', templateUrl: './in-home-list.component.html', styleUrls: ['./in-home-list.component.css'] }) export class InHomeListComponent implements OnInit { res: Food[]; error: string; constructor( private api: ApiService ){} ngOnInit() { // 在组件内订阅获取结果 this.api.getInHomeList().subscribe({ next: r => this.res = r, error: e => this.error = e }); } }
可选扩展:服务内维护共享状态
如果你的场景需要多个组件共享同一份接口返回的数据,不需要重复发起请求,可以在服务内用BehaviorSubject维护状态,组件订阅状态流即可,这种场景才需要在服务内部发起订阅。
内容的提问来源于stack exchange,提问作者Mattia
相关产品推荐
相关产品推荐

