Angular中inject()生成多余实例的问题确认与解决咨询
Angular中
inject()获取服务实例问题排查与解决 问题背景
我想确认在Angular中使用inject()是否会获取服务的不同实例,这会不会是我代码失效的原因。
我的路由配置代码如下:
{ path: 'recipes', component: RecipesComponent, resolve: {data: () => inject(HttpService).fetchRecipes()}, children: [ // 子路由配置 ] },
HttpService的代码:
@Injectable({ providedIn: 'root' }) export class HttpService { constructor(private recipeService: RecipeService, private http: HttpClient, private authSerivce: AuthService) {} storeRecipes() { const recipes = this.recipeService.getRecipes() this.http.put('https://ng-recipe-shopping-f9c65-default-rtdb.firebaseio.com/recipes.json', recipes) .subscribe(respone => { console.log(respone) }) } ngOnInIt() { } fetchRecipes() { let authId: string this.authSerivce.userCred.subscribe(authToken => { authId = authToken }) return this.http.get<Recipe[]>(`https://ng-recipe-shopping-f9c65-default-rtdb.firebaseio.com/recipes.json?auth=${authId}`) .pipe(map(recipes => { return recipes.map(recipe => { return { ...recipe, ingredients: recipe.ingredients ? recipe.ingredients : [] } }) }), tap(recipes => { this.recipeService.fetchRecipes(recipes) })) } }
当前问题:在路由模块中调用fetchRecipes()时,authSerivce.userCred的订阅并未执行,但应用其他地方调用userCred.next(/* value */)是正常的。我怀疑是HttpService实例不一致导致的,想知道怎么解决。我是Angular新手,已经看了约60%的官方依赖注入文档,没找到解决方案。
问题分析与解决方案
1. inject()获取的实例是否为根实例?
不会存在实例不一致的问题。你的HttpService配置了providedIn: 'root',这意味着该服务由根注入器提供,无论用构造函数注入还是inject()方法,只要注入上下文未限定在组件/模块级别,获取的都是同一个全局根实例。所以实例不一致不是当前问题的根源。
2. 真正问题:异步竞态导致订阅未生效
你在fetchRecipes()中的逻辑存在异步顺序问题:先订阅userCred,然后立刻发起HTTP请求,但订阅是异步操作——当你调用http.get时,authId可能还没被赋值(要么userCred的next在订阅之后才触发,要么之前触发的值没被当前订阅捕获),导致请求参数错误,同时订阅的回调看起来没执行。
修正方法:用RxJS操作符把异步流串联起来,确保拿到有效authId后再发起请求:
fetchRecipes() { return this.authSerivce.userCred.pipe( // 只取第一个有效token,避免重复触发请求 first(authToken => !!authToken), // 拿到token后切换到HTTP请求流 switchMap(authId => { return this.http.get<Recipe[]>(`https://ng-recipe-shopping-f9c65-default-rtdb.firebaseio.com/recipes.json?auth=${authId}`) }), map(recipes => { return recipes.map(recipe => { return { ...recipe, ingredients: recipe.ingredients ? recipe.ingredients : [] } }) }), tap(recipes => { this.recipeService.fetchRecipes(recipes) }) ) }
3. 额外注意点
- 你的
HttpService里的生命周期钩子拼写成了ngOnInIt,正确写法是ngOnInit,这个错误会导致钩子无法执行,建议修正。 - 路由resolve中的函数返回Observable即可,Angular会自动订阅并完成resolve流程,无需手动订阅。
内容的提问来源于stack exchange,提问作者Issac Howard
相关产品推荐
相关产品推荐

