将可观察集合与可观察集合合并

时间:2017-12-14 17:43:12

标签: angular typescript rxjs observable

我有一个API调用,它返回一个可观察的对象集合。对于该可观察集合中的每个对象,我需要进行另一个API调用以获得可观察的值。

将可观察集合与一组可观察对象合并的正确方法是什么,以便结果是一个可观察的集合,我们可以去掉额外的数据?

I.E:(1:n) - > 1

具体

// getMarkets API response:
[   {
    "data": [
      {
        "mkt_name": "X",
        ...
      },
      {...}, {...}, {...} 
      //there is a lot of these, cardinality changes over time
    ]}
]
//getTicker(market=X) API response:
[   {
    "data": [
      {
        "last_trade": "651.4000000000",
        ...
      }
      //there is only one of this, "last_trade" value changes a lot more over time
    ],
    "notifications": []
    }
]

我需要

//getMarketsWithTickers Service response (! Also Observable !)
[ 
  {"market" : "X", "last_trade" : "651.4000000000" },  
  {...}, 
  {...}, 
  {...}
]

如何使用getMarketWithTickers / getMarkets可观察对象实施getTicker

注意:我是整个RxJS的新手。

由于

1 个答案:

答案 0 :(得分:3)

这是一个完整的可运行示例,展示了您可以做的事情;

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/map';

// what you already have (simulated):
interface Market {
  name: string;
}

interface Trade {
  lastTrade: string;
}

function getMarkets() {
  return Observable.of({data: [{name: 'm1'}, {name: 'm2'}, {name: 'm3'}] as Array<Market>})
}

function getTicker(marketName: string) {
  return Observable.of({data: {lastTrade: marketName.substring(1)}});
}

// what you can do:
getMarkets()
  .map(obj => obj.data.map(market => market.name)) //1
  .switchMap(marketNames =>
    Observable.forkJoin( // 4
      ...marketNames.map(market => getTicker(market) // 2
      .map(ticker => +ticker.data.lastTrade))) // 3
  )
  .subscribe(trades => console.log(trades.join(', ')));

简短说明(阅读文档了解更多详情):

  1. 使用地图运算符将您的可观察市场集合转换为可观察的市场名称
  2. 当您收到市场名称数组时,您可以为每个市场名称创建一个可观察到的Ticker。
  3. 每个可观察到的Ticker被转换为一个observable的lastTrade,一个再次使用map运算符
  4. 使用forkJoin方法创建一个observable,发出一个数组,其中包含lastTrade的每个observable的(最后)发出的事件