0

除了在 RxJS 的下一个 pipable 运算符中获取其响应数据之外,我还想传递 URL。您认为实现这一目标的最明智的方法是什么?提前致谢。

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

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

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 及其响应数据。

4

3 回答 3

8

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

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();
于 2019-05-08T14:11:16.100 回答
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();

这将有效地将两者url和结果映射this.getData(url)到可以在tap().

这是您修改的示例以显示此操作。

注意:结果选择器正在被弃用/删除。虽然这个解决方案目前可能有效,但在未来版本的 RxJS (7.x) 中将不再可行。@martin 提供的答案肯定更“面向未来”。

希望这会有所帮助!

于 2019-05-08T14:15:48.887 回答
0

对于给定的代码示例,Martin 的答案是正确的。

然而,对于更复杂和更长的运算符链,将先前的值传递给后续运算符可能成为一项相当复杂的任务。特别是在使用更高级的运算符时,例如扩展运算符。

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

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();

但同样,对于更简单的运算符链,向返回的对象添加值是可行的方法。

于 2020-05-06T14:11:48.030 回答