【问题标题】:Transform data in an Observable在 Observable 中转换数据
【发布时间】:2018-07-11 04:53:40
【问题描述】:

我正在从我的 Angular 服务上的 Observable 中检索项目列表。在每个项目中,我都有一个包含主题列表的数组。对于每个主题,我都需要再次调用以获取其详细信息(例如名称、描述等)。

数据结构:

- post1
  - subjects: ['books', 'cars', 'movies']

使用该列表,我有来自每个主题的 id,但我需要返回一个包含属于该帖子的所有主题(及其详细信息)的 observable。

AppService.ts

getPost(id: string): Observable<Post> {
    return Observable.of({id: id, subjects: ['books', 'cars', 'movies']});
}

getSubjects(id: string): Observable<Subject[]> {
    return this.getPost(id).pipe(
        map((post: Post) => post.subjects),
        mergeMap((subjects: string[]) => subjects.map((id: string) => this.getSubject(id))),
        switchMap(list => list),
    );
}

getSubject(id: string): Observable<Subject> {
    switch (id) {
        case 'books':
            return Observable.of({id: 'books', name: 'Books'});
        case 'cars':
            return Observable.of({id: 'cars', name: 'Cars'});
        case 'movies':
            return Observable.of({id: 'movies', name: 'Movies'});
    }
}

它返回一个对象流,但我想返回一个包含所有主题的数组。

[DEMO]

【问题讨论】:

  • subjectService.get()的定义是什么?
  • 这是一个Observable&lt;Subject&gt;。我用demo 更新了我的问题。
  • @brians69 你需要检查subjectService.get(id)返回的类型。
  • 谢谢,里奇。是的,它返回的是对象流而不是数组。你知道我怎样才能返回一个包含所有主题的数组吗? demo
  • 是否有预定义(且相对较小)的主题集?如果是这样,检索所有主题的完整列表,然后为特定帖子归档列表可能是有意义的。

标签: javascript angular typescript rxjs observable


【解决方案1】:

那是因为你混淆了Observables.map().map()Array.prototype.map().map()

这行代码:

 mergeMap((subjects: string[]) => subjects.map((id: string) => this.getSubject(id)))

不返回Subjects 的数组;相反,它返回一个Observables 的数组,因为函数内的subject 参数是一个数组,而不是Observable。因此,那个特定的.map() 将返回一个this.getSubject(id) 的retyrn 类型的数组,它是一个Observables 的数组;正是你得到的行为。

如果要将所有Observables 解析为Subjects 的数组,则必须使用Observable.forkJoin.forkJoin() 组合所有可观察对象并并行触发它们。

getSubjects(id: string): Observable<Subject[]> {
    return this.getPost(id).pipe(
        map((post: Post) => post.subjects),
        mergeMap((subjects: string[]) => Observable.forkJoin([...subjects.map((id: string) => this.getSubject(id))])),
    );
}

现在你可以在你的组件中使用它了:

getSubjects(id).subscribe(values=>{
    console.log(values)//returns an array of Subjects
})

请注意,Observables.forkJoin 必须等待 所有 可观察对象完成后才能触发发射。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-19
    • 2020-12-01
    • 2017-09-24
    • 1970-01-01
    • 2020-04-02
    • 2019-03-24
    • 2021-05-24
    • 1970-01-01
    相关资源
    最近更新 更多