简体   繁体   English

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

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

A very common problem when using RxJs seems to be to want the result of one or more observables to then use them in subsequent ones.使用 RxJs 时的一个非常常见的问题似乎是希望一个或多个 observables 的结果然后在后续的那些中使用它们。

eg in pseudo-code (This is not rx or valid js syntax deliberately)例如在伪代码中(这不是 rx 或故意的有效 js 语法)

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

This can be done in an ugly way where you could subscribe to both and call one inside the other.. however, this is very messy and doesn't afford you much flexibility.这可以通过一种丑陋的方式来完成,您可以同时订阅两者并在另一个内部调用一个。但是,这非常混乱并且不能为您提供很大的灵活性。

eg (real syntax)例如(真正的语法)

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

This also means that nothing else can easily consume this stream as you're completing both of the observables.这也意味着当您完成这两个可观察项时,没有其他东西可以轻易地消耗这个 stream。

My specific use case requires the following:我的具体用例需要以下内容:

  1. An initial call to get $observable-A as it doesn't require anything else (it's a basic http GET call)获取 $observable-A 的初始调用,因为它不需要任何其他内容(这是一个基本的 http GET 调用)
  2. An http GET call to another service that requires data from $observable-A, which returns $observable-B对另一个服务的 http GET 调用需要来自 $observable-A 的数据,该服务返回 $observable-B
  3. Using both observable results (A + B) to create an object for my service (In my case, an Angular service) to return a single list.使用两个可观察结果 (A + B) 为我的服务创建一个 object(在我的例子中,一个 Angular 服务)返回一个列表。

I also need to be able to subscribe to this function inside my service, this is why going with the subscribe method above, won't work for me.我还需要能够在我的服务中订阅这个 function,这就是为什么使用上面的订阅方法对我不起作用的原因。

Snorre Danielsen nailed this problem and full credit for this solution goes to him. Snorre Danielsen 解决了这个问题,这个解决方案的全部功劳归于他。 I'd recommend having a look at this .我建议看看这个

The great thing about rxjs operators is their interoperability. rxjs 运算符的优点在于它们的互操作性。 You can mix and match almost everything to get your desired outcome.您可以混合搭配几乎所有东西以获得您想要的结果。

In short.简而言之。 The code answer to this question is below, and i'll explain it further.这个问题的代码答案如下,我会进一步解释。

$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 (or flatMap which is an alias) takes an observable as an input and projects it (just like a regular map function). mergeMap (或flatMap是别名)将 observable 作为输入并将其投影(就像常规的 map 函数一样)。 This means we can use its result as the input for $observable-B .这意味着我们可以使用它的结果作为$observable-B的输入。 Now this is great for when you actually want to only return the second observable result.现在,当您实际上只想返回第二个可观察结果时,这非常有用。 eg例如

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

Now, back to the main solution.现在,回到主要解决方案。 combineLatest is the key here. combineLatest是这里的关键。 It allows the mergeMap to essentially "wait" for the internal observable ( $observable-B ) to complete.它允许mergeMap基本上“等待”内部可观察对象( $observable-B )完成。 Without it, you're just going to return an observable to your next rxjs operator in the pipe , which is not what we want (as you're expecting to deal with regular operator functions inside a pipe ).没有它,您只会在pipe中向您的下一个 rxjs 运算符返回一个可观察值,这不是我们想要的(因为您期望在pipe中处理常规运算符函数)。

Because of this, we can take these new merged observables into the next part of the chain and use them together.正因为如此,我们可以将这些新合并的 observables 带入链的下一部分,并一起使用它们。 We use the of() function to re-create resultA , as combineLatest only takes observables as inputs and resultA is a completed observable in this state.我们使用of() function 重新创建resultA ,因为combineLatest仅将 observables 作为输入,而resultA是 state 中的完整 observable。

A hint: Take a look at the map(([resultA, resultB]) . The reason we use this notation to refer to our variables instead of the standard map(results) . Is so we can directly reference them without using results[0] for resultA or results[1] for resultB . Its just a lot easier to read this way.提示:看一下map(([resultA, resultB]) 。我们使用这个符号来引用我们的变量而不是标准map(results)的原因是这样我们可以直接引用它们而不使用results[0]用于resultAresults[1]用于resultB 。这样阅读起来要容易得多。


I hope this helps people out as I have yet to find a complete SO answer which covers this case.我希望这对人们有所帮助,因为我还没有找到涵盖此案例的完整 SO 答案。 Edits are very welcome as its complicated and I'm sure its not a perfect answer.编辑非常受欢迎,因为它很复杂,我相信它不是一个完美的答案。

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

相关问题 如何在 rxjs 中通过循环使用两个可观察函数一个在另一个内部? - How to use two observable functions one inside another with loop in rxjs? 使用 RXJS 一起返回两个 observables 的结果 - use RXJS to return results of two observables together 我将如何组合来自两个 Observable 的结果,但如果一个 observable 的返回比另一个更快,我将如何使用它的结果? - How would I combine the results from two Observables but also use result of one observable if it returns sooner than the other? 将RXJS可观察的结果合并为一个 - Combine RXJS observable results into one 如何使用 rxjs 从另一个可观察对象创建可观察的 object? - How to use rxjs to create an object observable from another observable? rxjs:如何从 catchError 返回另一个可观察的结果 - rxjs: how to return the result from another observable from catchError 如何使用RxJS处理数百个请求而不会崩溃? - How do I use RxJS to process hundreds of requests without crashing? RxJS:使用另一个observable过滤一个observable - RxJS : Filter one observable using another observable 如何根据结果进行可观察的调用? - How can I have an observable call another one based on the result? RXJS-如何使用2个不同的可观察结果作为函数调用的参数 - RXJS - How to use the result of 2 different observable as parameters for a function call
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM