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

查看:18
本文介绍了订阅嵌套的 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 的响应).我还需要订阅每个内部 observable,以便 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,但在这种情况下它似乎具有相同的结果.有没有办法订阅嵌套的 observable?

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?

推荐答案

我会这样做:

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天全站免登陆