javascript - 转换 Observable 中的数据

标签 javascript angular typescript rxjs observable

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

数据结构:

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

通过该列表,我获得了每个主题的 id,但我需要返回一个包含属于该帖子的所有主题(及其详细信息)的可观察值。

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 ]

最佳答案

那是因为你混淆了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 在触发发射之前必须等待所有可观察对象完成。

关于javascript - 转换 Observable 中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48553022/

相关文章:

javascript - 如何让页脚从 DOM 的第 3 页开始

angular - 使用 AOT 时,对传递给 forRoot 的对象所做的更改在注入(inject)时会被丢弃

typescript 类型推断失败?

javascript - 如何将 Css/JQuery 文件应用到 Android WebView 中的外部页面

javascript - HTML5 文件上传进度 - 仅限客户端

angular - 将路由器防护应用于除一名 child 之外的所有 child

node.js - Angular:创建 Angular 项目时出现新错误

reactjs - 使用 Typescript 和 React.Konva 指定 onClick 事件类型

angularjs - TypeScript 和 Angular - 何时使用模块与 IIFE

javascript - 在 Javascript/jQuery 中将大型 JSON 拆分为较小的部分