【问题标题】:Best way to pass data between RxJS pipable operators?在 RxJS pipable 操作符之间传递数据的最佳方式?
【发布时间】:2019-05-08 14:07:03
【问题描述】:

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

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

我尝试了一些运算符,但找不到合适的运算符。 (实际上,我什至不知道为什么将返回 observable 的函数传递给 mergeMap 会导致在 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 及其响应数据。

【问题讨论】:

    标签: angular rxjs rxjs-pipeable-operators


    【解决方案1】:

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

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

    【讨论】:

    【解决方案2】:

    查看mergeMapmergeMap(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 提供的答案肯定更“面向未来”。

    希望对您有所帮助!

    【讨论】:

    • 我选择了一款面向未来的,虽然这个仍然很有趣,谢谢!!
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2014-01-27
      • 2018-11-10
      • 2020-12-03
      • 2012-11-12
      • 1970-01-01
      • 2021-04-28
      • 2018-08-01
      • 1970-01-01
      相关资源
      最近更新 更多