[英]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:我的具体用例需要以下内容:
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 standardmap(results)
. Is so we can directly reference them without usingresults[0]
forresultA
orresults[1]
forresultB
. Its just a lot easier to read this way.提示:看一下
map(([resultA, resultB])
。我们使用这个符号来引用我们的变量而不是标准map(results)
的原因是这样我们可以直接引用它们而不使用results[0]
用于resultA
或results[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.