以可观察的方式转换数据 [英] Transform data in an Observable

查看:63
本文介绍了以可观察的方式转换数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm retrieving a list of items from an Observable on my Angular service. Inside every item, I have an array with a list of subjects. For every subject, I need to make another call to get its details (e.g. name, description, etc.).

数据结构:

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

有了这个列表,我得到了每个主题的 id ,但是我需要返回一个可观察到的信息,其中包含属于该帖子的所有主题(及其详细信息).

With that list, I have the id from every subject but I need to return an observable containing all subjects belonging to that post (and their details).

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'});
    }
}

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

It returns a stream of objects but I'd like to return an array with all subjects.

[演示]

[DEMO]

推荐答案

那是因为您混淆了.map()/map.html"rel =" nofollow noreferrer> Observables.map()

That is because you confused .map() of Observables.map() and the .map() of Array.prototype.map().

这行特殊代码:

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

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

does not return an array of Subjects; instead, it returns an array of Observables because the subject argument inside the function is an array, not an Observable. Hence, that particular .map() will return an array of the retyrn type of this.getSubject(id), which is an array of Observables; exactly the behaviour you are getting.

如果要将所有 Observables 解析为 Subjects 的数组,则必须使用

If you want to have all the Observables resolved into an array of Subjects, you will have to use Observable.forkJoin. .forkJoin() combines all the observables and fire them in parallel.

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))])),
    );
}

现在您可以在组件中使用它了

Now you can use it in your component:

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

请注意, Observables.forkJoin 在发射之前必须等待所有可观察对象完成.

Note that Observables.forkJoin will have to wait for all observables to complete before firing an emission.

这篇关于以可观察的方式转换数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆