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

问题描述 投票:0回答:1

在使用RxJs时,一个很常见的问题似乎是希望一个或多个观测值的结果,然后在后续的观测值中使用它们。

例如,在伪代码中(这不是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); 
        }
}

这也就意味着,在你完成这两个观测点的时候,没有任何其他东西可以轻易消耗这个流。

我的具体用例要求如下。

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

我还需要能够在我的服务内部订阅这个函数,这就是为什么用上面的订阅方法,对我来说是行不通的。

angular rxjs rxjs6 rxjs-pipeable-operators
1个回答
2
投票

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-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)来完成.如果没有它,你只会返回一个观测值到你的下一个rxjs操作符中的 pipe,这不是我们想要的(因为你期望在一个 pipe).

正因为如此,我们可以将这些新合并的观测值带入链的下一部分,并一起使用它们。我们使用 of() 函数来重新创建 resultA作为 combineLatest 只将观测值作为输入,并且 resultA 是这种状态下的一个完整的可观察对象。

一个提示:看一下 map(([resultA, resultB]). 我们之所以用这个符号来表示我们的变量,而不是标准的 map(results). 是为了让我们可以直接引用它们,而无需使用 results[0] 对于 resultAresults[1] 对于 resultB. 它只是一个更容易阅读这种方式。

我希望这能帮助大家,因为我还没有找到一个完整的涵盖这个案例的SO答案。非常欢迎编辑,因为它的复杂性,我敢肯定它不是一个完美的答案。

© www.soinside.com 2019 - 2024. All rights reserved.