RxJS Observable返回数组,每次迭代运行另一个函数

gre*_*gor 5 javascript observable rxjs angularjs

我有一个函数getNews(),它基本上返回angular的http.get请求.请求的结果是Id的数组.我想迭代我得到的这个数组并运行另一个http.get请求(函数getItem(id)),然后返回从服务器接收的单个Id的对象.

我试过这样使用它:

  getLatest() {
    return this.http.get('all_news_url')
    .map(res => res.json())
    // I even tried creating Observable from array and get only 5 elements
    //.map(res => Observable.from(res.json()))
    //.take(5)
    .map((data) => this.getItem(data))
    .subscribe(
      data => {
        console.log(data);
      }
    )
  }

  getItem(itemId: any): Observable<any> {
    console.log('item id', itemId);

    return this.http.get(this.generateUrl(`item/${itemId}`))
    .map(res => res.json());
  }
Run Code Online (Sandbox Code Playgroud)

显然,这不起作用.getItem()函数的参数总是作为Id的整个数组传递.

感谢大家参与这个问题.

Can*_*yen 10

您可能希望使用concatMap运算符而不是map.concatMap将返回的Observable展平为源Observable,而map返回一个observable的observable.

如果您希望getItem()中的数据与'all_news_url'中列出的顺序相同,您可以尝试类似

this.http.get('all_news_url')
.concatMap(res => Observable.from(res.json()).take(5))
.concatMap((data) => this.getItem(data))
.subscribe(
  data => {
    console.log(data);
  }
);
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,对getItem()的调用将是同步的,即一次只有一个请求'item/$ {itemId}',并按顺序

如果您不关心订单并想通过一次发送多个请求来加速它们,请将第二个concatMap更改为mergeMap.请注意,请求(对于item/itemId)仍然是有序的,但不能保证响应的顺序.您可以提供最大并发请求作为mergeMap 的第三个参数(通过传递undefined或null忽略第二个参数).

.concatMap(res => Observable.from(res.json()).take(5))
.mergeMap((data) => this.getItem(data), null, 3)
Run Code Online (Sandbox Code Playgroud)

传递1作为mergeMap的第三个参数将等同于concatMap