Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 链接多个观测值并重用链中已执行的观测值的结果_Javascript_Typescript_Rxjs_Observable - Fatal编程技术网

Javascript 链接多个观测值并重用链中已执行的观测值的结果

Javascript 链接多个观测值并重用链中已执行的观测值的结果,javascript,typescript,rxjs,observable,Javascript,Typescript,Rxjs,Observable,我想将以下函数组合起来以得到一个结果 函数a(){ 返回rx.of(42); } 函数b(值){ 返回rx.of(值*2); } 功能c(val1、val2){ 返回rx.of({ 原件:val1, 修改:val2 }) } 这些是简化的变体-它们实际上是HTTP请求。执行b需要a的结果,a和bs结果是执行c的先决条件。我唯一能想到的就是将它们全部包装在.subscribe()调用中,但这看起来并不正确。但我想不出更好的办法来解决这个问题: //坏的 新的可观察对象(观察者=>{ 订阅( 结果

我想将以下函数组合起来以得到一个结果

函数a(){
返回rx.of(42);
}
函数b(值){
返回rx.of(值*2);
}
功能c(val1、val2){
返回rx.of({
原件:val1,
修改:val2
})
}
这些是简化的变体-它们实际上是HTTP请求。执行
b
需要
a
的结果,
a
b
s结果是执行
c
的先决条件。我唯一能想到的就是将它们全部包装在
.subscribe()
调用中,但这看起来并不正确。但我想不出更好的办法来解决这个问题:

//坏的
新的可观察对象(观察者=>{
订阅(
结果a=>{
b(结果a)。订阅(
结果_b=>{
c(结果a,结果b)。订阅(
结果_c=>{
观察员:下一个(c);
}
)
}
)
}
)    
}).订阅(
结果=>console.log(结果)
)

我确实知道有诸如
pipe
concat
等操作符,但我不知道如何在这种特殊情况下应用它们,在这种情况下,一个
可观察的
的结果仍然需要用于以后执行的另一个。我如何通过使用适当的RxJS技术来简化这一点?

您可以尝试的是这样的,注释是内联添加的

a().pipe(
  // concatMap ensures that the order of notification is maintained, i.e. a() emits its next value only after b() has finished processing the previous one
  concatMap(valA => b(valA).pipe(
    // via this map we can return both the result of b() and also the parameter received, i.e. the result of a()
    map(valB => {
       return {valA, valB}
    })
  ),
  // here again, with concatMap, we ensure the order of notification is maintained
  concatMap(({valA, valB}) => c(valA, valB))
)
这是一种典型的模式,在使用RxJS和http时可能会遇到很多次


如果您想看到更多这样的模式,可以阅读。

与您的示例直接等效的是
mergeMap

a()管道(
合并映射(a=>
b(a)管道(
合并映射(b=>c(a,b))
)
)
)
.subscribe(console.log)

如果顺序很重要(一旦这些是异步的,而不仅仅是由的
生成的),那么您将希望使用
concatMap
。但是总体结构是相同的。

如果
a
b
观察值已完成,您可以像这样使用
forkJoin
操作符:

const{of,forkJoin}=rxjs;
const{mergeMap}=rxjs.operators;
函数a(){
归还(42);
}
函数b(值){
返回(值*2);
}
功能c(val1、val2){
归还({
原件:val1,
修改:val2
})
}
const init=a();
分叉连接(
初始化,
初始管道(合并映射(b))
).pipe(合并映射([a,b])=>c(a,b)))
.subscribe(console.log)