You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 17中TranslocoLoader的Observable仅触发一次问题

问题:TranslocoLoader的Observable写法多次调用仅首次执行map逻辑

我实现了如下TranslocoLoader服务:

// transloco-loader.ts

import { inject, Injectable } from '@angular/core';
import {TranslocoLoader } from '@ngneat/transloco';
import { map, take} from 'rxjs';
import { CFV2 } from '@go/shared-data-access-angular-config';

@Injectable({ providedIn: 'root' })
export class TranslocoHttpLoader implements TranslocoLoader {
  private _configFacade = inject(CFV2.ConfigFacade);
  
  getTranslation(lang: string) {

    // 每次都会执行到这里
    console.log('function gets called each time');

    return this._configFacade.configState$.pipe(
      take(1),
      map((state) => {

        // 但这里仅执行一次!即使configState$没有变化!
        console.log('But we get here ONLY ONCE!');

        return { t: 'something' };
      }),
    );
  }
}

当我调用getTranslation方法两次(针对同一语言)时,仅第一次会进入pipe中的map操作。我使用的是Angular 17,请问忽略了什么?

我通过async语法解决了该问题:

async getTranslation(lang: string): Promise<{ t: string }> {
    console.log('function gets called each time');

    const state = await firstValueFrom(
      this._configFacade.configState$.pipe(take(1)),
    );
    console.log('And we get here each time too!');

    return { t: 'something' };
  }

但我仍想了解为何Observable写法无法正常工作!


原因分析

核心问题出在Transloco的内置缓存机制:

  • 当getTranslation返回Observable类型结果时,Transloco会对相同语言的翻译请求做缓存:第一次调用时,它会订阅你返回的Observable,拿到结果后直接缓存;第二次调用同一语言的getTranslation时,Transloco会直接返回缓存的结果,不会再去订阅你新生成的Observable,因此map里的逻辑不会执行。
  • 而改用async/await返回Promise时,每次调用getTranslation都会生成一个全新的Promise实例。Transloco对Promise的处理逻辑是,即使是同一语言,也会等待这个新Promise完成(其缓存机制未对Promise做复用),因此每次都会执行到await后的代码。

另外补充:你的configState$如果是BehaviorSubject这类热Observable,本身会保留最新值,但问题的核心不在Observable的冷热属性,而是Transloco的缓存逻辑导致第二次没有订阅新的Observable。

内容的提问来源于stack exchange,提问作者Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:53:13