网站搜索

typescript - 在服务函数中将 Rxjs Transform API 的结果 Observable 转换为另一个 Observable


我有一个加载器服务,其结果是 Observable<string>,其中包含一个 CSV 文件。每一行代表一个不同的实体(例如 Person 对象),用逗号分隔的部分表示该人的属性,例如 id、年龄、姓名等。

加载器服务功能是:

loadtTextFile(path: string): Observable<string> 

loadAllPerson 服务函数是:

loadAllPerson(): Observable<Array<Person>> 

我想在一个包装器 loadAllPerson 中调用 loadtTextFile,其中所需的输出是:Observable<Array<Person>>

我如何确保该服务只有在 CSV 的所有行都解析到结果 Observable<Array<Person>> 时才返回?

可能一开始我们应该等待loader service的结果,然后将其解析为Person数组,并以Observable<Array<Person>>返回结果

以下代码部分将内容解析为 Person 数组,其中 contentObservable 是一个 Observable<string>

const contentObservable = this.fileLoaderService.loadtTextFile();

contentObservable.mapTo(fileContent => {
    const rowsOfContent = fileContent.split('\n');
    rowsOfContent.forEach((row: string) => {
      const cols = row.split(',');
      // has valid numeric value of id and age?
      if (!Number.isNaN(+cols[0]) && !Number.isNaN(+cols[3])) {
        const person = new Person(+cols[0], cols[1], cols[2], +cols[3], cols[4],
          cols[5], cols[6], cols[7], new Date(cols[8]));
        personData.push(person);
      }
    });
    console.log(JSON.stringify(personData));
});

答案#1

`map` 操作符是你的朋友。可以这样尝试:

loadAllPerson(): Observable<Person[]> {
  return loadTextFile(PATH).pipe(
    map((csv: string) =>
      csv.split('\n')
         .map((rows: string[]) => rows.map((row: string) => row.split(',')))
         .map((table: string[][]) => 
           table.filter((cols: string[]) => !Number.isNaN(+cols[0]) && !Number.isNaN(+cols[3]))
                .map((cols: string[]) => new Person(+cols[0], cols[1], cols[2], +cols[3], cols[4], cols[5], cols[6], cols[7], new Date(cols[8])))
         )
    )),
  );
}