繁体   English   中英

RXJS 如何在另一个中使用一个可观察的结果(然后将这两个结果一起处理)

[英]RXJS How do I use the result of one observable in another (and then process those two results together)

使用 RxJs 时的一个非常常见的问题似乎是希望一个或多个 observables 的结果然后在后续的那些中使用它们。

例如在伪代码中(这不是 rx 或故意的有效 js 语法)

var someResult = $observable-A; // wait to complete
var finalResult = $observable-B(someResult.aValueINeed);

这可以通过一种丑陋的方式来完成,您可以同时订阅两者并在另一个内部调用一个。但是,这非常混乱并且不能为您提供很大的灵活性。

例如(真正的语法)

$observable-A.subscribe(resultA => { 
    $observable-B(resultA.aValueINeed)
        .subscribe(resultB => { 
            console.log('After everything completes: ', resultB); 
        }
}

这也意味着当您完成这两个可观察项时,没有其他东西可以轻易地消耗这个 stream。

我的具体用例需要以下内容:

  1. 获取 $observable-A 的初始调用,因为它不需要任何其他内容(这是一个基本的 http GET 调用)
  2. 对另一个服务的 http GET 调用需要来自 $observable-A 的数据,该服务返回 $observable-B
  3. 使用两个可观察结果 (A + B) 为我的服务创建一个 object(在我的例子中,一个 Angular 服务)返回一个列表。

我还需要能够在我的服务中订阅这个 function,这就是为什么使用上面的订阅方法对我不起作用的原因。

Snorre Danielsen 解决了这个问题,这个解决方案的全部功劳归于他。 我建议看看这个

rxjs 运算符的优点在于它们的互操作性。 您可以混合搭配几乎所有东西以获得您想要的结果。

简而言之。 这个问题的代码答案如下,我会进一步解释。

$observable-A.pipe(
    mergeMap(resultA => {
        return combineLatest(
            of(resultA),
            $observable-B(resultA)
        )
    }),
    map(([resultA, resultB]) => {
        // you can do anything with both results here
        // we can also subscribe to this any number of times because we are doing all the processing with
        // pipes and not completing the observable
    }
)

mergeMap (或flatMap是别名)将 observable 作为输入并将其投影(就像常规的 map 函数一样)。 这意味着我们可以使用它的结果作为$observable-B的输入。 现在,当您实际上只想返回第二个可观察结果时,这非常有用。 例如

$observable-A.pipe(
    mergeMap(resultA => $observable-B(resultA)),
    map((resultB) => {
        // resultA doesn't exist here and we can only manipulate resultB
    }
)

现在,回到主要解决方案。 combineLatest是这里的关键。 它允许mergeMap基本上“等待”内部可观察对象( $observable-B )完成。 没有它,您只会在pipe中向您的下一个 rxjs 运算符返回一个可观察值,这不是我们想要的(因为您期望在pipe中处理常规运算符函数)。

正因为如此,我们可以将这些新合并的 observables 带入链的下一部分,并一起使用它们。 我们使用of() function 重新创建resultA ,因为combineLatest仅将 observables 作为输入,而resultA是 state 中的完整 observable。

提示:看一下map(([resultA, resultB]) 。我们使用这个符号来引用我们的变量而不是标准map(results)的原因是这样我们可以直接引用它们而不使用results[0]用于resultAresults[1]用于resultB 。这样阅读起来要容易得多。


我希望这对人们有所帮助,因为我还没有找到涵盖此案例的完整 SO 答案。 编辑非常受欢迎,因为它很复杂,我相信它不是一个完美的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM