代码之家  ›  专栏  ›  技术社区  ›  Thomas Schneiter

从rxjs订阅返回函数

  •  0
  • Thomas Schneiter  · 技术社区  · 8 年前

    这是一个关于如何使用angular-l10n翻译模块的问题,但由于这是一个更加特定于typescript的问题,我将其发布在这里。

    要动态配置模块(例如设置默认语言),我必须使用以下方法:

    load(): Function {
      this.localeConfig.language = 'en';
      return () => this.l10nLoader.load();
    }
    

    localeConfig l10nLoader 都是注射的。

    return () => this.l10nLoader.load(); 必须在最后执行,才能在配置后实际显示页面。

    我想做的是从api加载语言,然后设置配置。

    我在返回 Observable 然后在load()函数中订阅它。

    load(): Function {
      this.languageService.getDefaultLanguage().subscribe(
        lang => {
          this.localeConfig.language = lang;
          return ???
        }
      );
    }
    

    问题是:我不知道怎么回去 this.l10nLoader.load(); 在订阅结束时。如果我在函数结束时返回它,它将在订阅结束之前完成。

    订阅完成后,如何返回Function类型的内容?

    3 回复  |  直到 8 年前
        1
  •  1
  •   Vitalii Chmovzh    8 年前

    你不能用 return ,因为 load() 函数是异步的。我建议做的是改变 加载() 将值返回到 Observable<Function> 并创建 new Observable 在里面。

    以下是代码片段:

    load(): Observable<Function> {
       return new Observable(observer => {
           this.languageService.getDefaultLanguage().subscribe(
              lang => {
                 this.localeConfig.language = lang;
                 observer.next(this.l10nLoader.load);
                 observer.complete();
              }
           );
       });
    }
    

    之后,可以通过以下方式调用此函数:

    load().subscribe(fn => fn());
    
        2
  •  0
  •   user4676340 user4676340    8 年前

    在Vanilla JS中,可以使用回调。

    例如,您可以这样做:

    load(cb: Function): Function {
      this.languageService.getDefaultLanguage().subscribe(lang => {
        this.localeConfig.language = lang;
        cb(lang);
      });
    }
    

    现在,您可以这样调用函数:

    this.myL10nService.load(lang => {
      console.log('selected language is ' + lang);
    });
    
        3
  •  0
  •   Thomas Schneiter    8 年前

    我找到了一个有效的解决方案。
    使用 .toPromise() 而不是 .subscribe() 然后返回 l10nLoader.load(); 由于这个承诺解决了我的问题。

    语言配置。服务:

    @Injectable()
    export class LocalizationConfig {
      constructor(
          public l10nLoader: L10nLoader,
          @Inject(TRANSLATION_CONFIG) private translationConfig: TranslationConfig,
          @Inject(LOCALE_CONFIG) private localeConfig: LocaleConfig,
          private language: LanguageService
      ) { }
    
      load(): Promise<void> {
        return this.language.getUserLanguages().toPromise()
        .then(
          res => {
            this.localeConfig.language = res.language;
            return this.l10nLoader.load(); // this is important!!
          })
        .catch(  
          err => {
            // set default language or desired strategy
            return this.l10nLoader.load();   
          }
        );
      }
    }
    
    export function initLocalization(localizationConfig: LocalizationConfig): Function {
      return () => localizationConfig.load();
    }
    

    应用程序。模块:

    providers: [
      ...
      {
        provide: APP_INITIALIZER,
        useFactory: initLocalization,
        deps: [LocalizationConfig],
        multi: true,
      },
      ...