Rxjs结合动态的可观察量

睿智先生

我正在为@ ngx-translate创建一个加载器,该加载器根据所选语言从目录加载多个JSON翻译文件。

我当前加载文件的方式是通过一个index.json文件,文件包含具有该语言翻译文件的名称和扩展名的数组。

翻译文件的结构如下:

- assets
  - i18n
    - index.json <-- Contains an array of translation file names
    - en_US
      - home.json
      - header.json
    - de_DE
      - home.json
      - header.json

的示例index.json如下:

[
  "home.json",
  "header.json"
]

由于AngularHttpClientModule无法加载目录的内容或目录中文件的名称(它只能加载单个json文件),因此我需要在中定义名称index.json

这也意味着我必须先加载index.json,然后再加载目录中的所有其他文件。

在代码中,这意味着:

  1. 加载index.json
  2. 循环遍历文件名数组
  3. 在单独的请求中加载每个文件
  4. 全部完成后,将所有文件内容合并为一个对象

我尝试过的

 public getTranslation(language: string): Observable<any> {
    return this.getIndexFile(language)
      .pipe(
        map((fileNames: string[]) => {
          const promises = [];

          for (const name of fileNames) {
            const path = Translation.replaceUrlPlaceholder(this.path, language);
            promises.push(this.http.get(path + '/' + name + '.json').toPromise());
          }

          return Promise.all(promises);
        }),
      );
  }

因此,我已经尝试过用Promise进行尝试,但这显然行不通(因为必须返回一个Observable)。同样,这里描述的解决方案对我不起作用,因为我需要动态地创建无限数量的可观察对象,并等待它们完成之后才能开始第4步。(合并所有文件)。

正确的方法应该是什么?


  • 角度的 7.1.0
  • RxJS 6.3.3
  • @ ngx-translate /核心 11.0.1

更新资料

Stackblitz在这里:结合可观察物

睿智先生

因此,在搜索并尝试了更多方法之后,我找到了答案的解决方案。那里有两个问题:

1.平面图与地图

我使用map()而不是flatMap区别在于,当第一个可观察对象完成时,flatMap将执行。这样,直到flatMap observable完成,订阅才能获得结果。

2. Promise.all与fork

可观察的相当于Promise.all()forkJoin()ForkJoin将并行执行所有可观察变量,并在一个数组中返回所有可观察变量的结果。


结果

因此,更新上面的代码将导致以下堆栈闪电:解决方案

或在代码中:

  public getTranslation(language: string): Observable<any> {
    return this.getIndexFile(language)
      .pipe(
        flatMap((fileNames: string[]) => {
          const observables: Observable<any>[] = [];

          for (const name of fileNames) {
            const path = 'assets/i18n/' + language + '/' + name + '.json';
            observables.push(this.http.get(path));
          }

          // Run all the observables in parallel
          return forkJoin(observables);
        }),
      );

关注点分离

我的代码在一个函数中包含多个动作,这使得它很难测试。所以应该分开。@trichetriche制作了一个包含关注点分离的版本。

请参阅他的Stackblitz以获取代码:Stackblitz

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章