在RxJS可插值运算符之间传递数据的最佳方法?

时间:2019-05-08 14:07:03

标签: angular rxjs rxjs-pipeable-operators

除了要在RxJS的下一个可插入运算符中获取其响应数据之外,我还希望传递URL。您认为实现这一目标的最明智的方法是什么? 预先感谢。

这里是一个例子。 https://stackblitz.com/edit/angular-rxjs-passing-data-to-next-operator-question

我尝试了一些运算符,但找不到合适的运算符。 (实际上,我什至都不知道为什么传递返回可观察到mergeMap的函数会导致在下一个运算符中获取数据作为函数的参数...)

from([
  'https://jsonplaceholder.typicode.com/posts',
  'https://jsonplaceholder.typicode.com/comments',
  'https://jsonplaceholder.typicode.com/albums',
])
  .pipe(
    mergeMap(url => this.getData(url)),
    tap(posts => console.log(posts[0])), // I want to get url too here!!
  ).subscribe();

我希望在pipable运算符中成对获得url及其响应数据。

3 个答案:

答案 0 :(得分:5)

您可以将响应映射到您想要的任何内容:

from([
  'https://jsonplaceholder.typicode.com/posts',
  'https://jsonplaceholder.typicode.com/comments',
  'https://jsonplaceholder.typicode.com/albums',
]).pipe(
    mergeMap(url => this.getData(url).pipe(
      map(response => ({ response, url })),
    )),
    tap(response => console.log(response)),
  ).subscribe();

答案 1 :(得分:1)

查看mergeMap mergeMap(project: function: Observable, resultSelector: function: any, concurrent: number): Observable的签名,可以使用resultSelector参数:

from([
  'https://jsonplaceholder.typicode.com/posts',
  'https://jsonplaceholder.typicode.com/comments',
  'https://jsonplaceholder.typicode.com/albums',
])
  .pipe(
    mergeMap(url => 
      this.getData(url),
      (outerValue, innerValue) => ({ url: outerValue, posts: innerValue })),
    tap(({ posts, url })=> {
      console.log(posts);
      console.log(url);
    })
  ).subscribe();

这将有效地将urlthis.getData(url)的结果映射到可以在tap()中使用的对象。

这是您对example进行的修改,以显示其实际效果。

注意:结果选择器位于process of being deprecated/removed中。尽管此解决方案当前可能有效,但在RxJS的未来版本(7.x)中将不再可行。 @martin提供的答案肯定更“面向未来”。

希望有帮助!

答案 2 :(得分:0)

马丁的答案是给定代码示例的正确答案。

但是对于更复杂和更长的运算符链,将先前的值传递给后续的运算符可能会变得非常复杂。尤其是在使用更高级的运算符(如扩展运算符)时。

在这种情况下,我更喜欢使用闭包来存储这些值:

const myStream$ = () => {
   const urls = [
      'https://jsonplaceholder.typicode.com/posts',
      'https://jsonplaceholder.typicode.com/comments',
      'https://jsonplaceholder.typicode.com/albums',
  ];
  let dataUrl;
  return from(urls).pipe(
      mergeMap(url => {
         dataUrl = url;
         return this.getData(url)
      }),
    // ... assuming more operators are called here ... //
    tap(posts => console.log(posts[0], dataUrl))
  );
};

myStream$().subscribe();

但是,对于更简单的运算符链,向返回的对象添加值是解决问题的方法。