订阅嵌套的Observable [英] Subscribing to a nested Observable

查看:31
本文介绍了订阅嵌套的Observable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,该应用程序发出一个http请求以获取项目列表,然后对列表中的每个项目进行http请求以获取有关每个项目的更多详细信息.有效地:

I have an app that makes one http request to get a list of items and then makes an http request for each item in the list to get more detailed information about each item. Effectively:

class ItemsService {
  fetchItems() {
    return this.http.get(url)
    .map(res => res.json())
    .map(items => items.map(this.fetchItem(item)));
  }

  fetchItem(item: Item) {
    this.http.get(`${url}/${item.id}`)
    .map(res => res.json());
  }
}

然后,我将执行类似itemsService.fetchItems().subscribe(items => console.log(items))的操作,但是最终发生的是,我得到了一个可观察对象数组(每个来自fetchItem的响应).我还需要订阅每个内部可观察对象,以便实际上触发fetchItem请求.

Then I'll do something like itemsService.fetchItems().subscribe(items => console.log(items)) but what ends up happening is I get an array of observables (each response from fetchItem). I need to subscribe to each of the internal observables as well so that the fetchItem request actually gets triggered.

我也尝试过使用flatMap代替map,但是在这种情况下,它似乎具有相同的结果.有什么方法可以订阅嵌套的可观察对象?

I've also tried using flatMap instead of map but it seems to have the same result in this case. Is there any way for the nested observable to be subscribed to?

推荐答案

我将按照以下方式进行操作:

I'd do it like the following:

function mockRequest() {
    return Observable.of('[{"id": 1}, {"id": 2}, {"id": 3}]');
}
function otherMockRequest(id) {
    return Observable.of(`{"id":${id}, "desc": "description ${id}"}`);
}

class ItemsService {
    fetchItems() {
        return mockRequest()
            .map(res => JSON.parse(res))
            .concatAll()
            .mergeMap(item => this.fetchItem(item));
    }

    fetchItem(item: Item) {
        return otherMockRequest(item.id)
            .map(res => JSON.parse(res));
    }
}

let service = new ItemsService();
service.fetchItems().subscribe(val => console.log(val));

观看现场演示: http://plnkr.co/edit/LPXfqxVsI6Ja2J7RpDYl?p=preview

我正在使用 .concatAll() 将对象数组(例如[{"id": 1}, {"id": 2}, {"id": 3}])转换为单独的值,分别由{"id": 1}{"id": 2}{"id": 3}发出(到目前为止,这是未公开的功能).然后,我使用 mergeMap() 来在单独的请求中获取其内容,并将其结果合并到运算符链中.

I'm using a trick with .concatAll() to convert an array of Objects such as [{"id": 1}, {"id": 2}, {"id": 3}] into separate values emitted one by one {"id": 1}, {"id": 2} and {"id": 3} (as of now it's an undocumented feature). Then I use mergeMap() to fetch their content in a separate request and merge it's result into the operator chain.

此plnkr示例打印到控制台:

This plnkr example prints to console:

{ id: 1, desc: 'description 1' }
{ id: 2, desc: 'description 2' }
{ id: 3, desc: 'description 3' }

这篇关于订阅嵌套的Observable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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