Javascript 如何展平RXJS中的嵌套调用并最终调用最后一个调用?
我们如何才能最好地将下面的呼叫扁平化。RxJS新手,试图理解如何简化它。阅读flatMap、forkJoin、switchMap和mergeMap,没有找到正确的路径来集成下面的内容,也不确定下面的场景中哪一个是最好的Javascript 如何展平RXJS中的嵌套调用并最终调用最后一个调用?,javascript,asynchronous,callback,rxjs,nested,Javascript,Asynchronous,Callback,Rxjs,Nested,我们如何才能最好地将下面的呼叫扁平化。RxJS新手,试图理解如何简化它。阅读flatMap、forkJoin、switchMap和mergeMap,没有找到正确的路径来集成下面的内容,也不确定下面的场景中哪一个是最好的 const useful = []; a.get('abc'). subscribe((abcdatas) => { abcdatas.forEach(abcdata => { if(abcdata.exist) { b.get('
const useful = [];
a.get('abc').
subscribe((abcdatas) => {
abcdatas.forEach(abcdata => {
if(abcdata.exist) {
b.get('def').
subscribe((defdatas) => {
useful.push(defdatas.someval);
});
}
});
})
if(useful.length) {
c.get('ghi').
subscribe((ghidata) => {
completed...
});
}
使现代化
更新我的问题,谢谢你的回复。有用的是一个结果的全局数组,在我的例子中,应该从嵌套调用填充该数组。最后应该传递给最后一个调用
我正在尝试的步骤:
使用诸如
switchMap
或mergeMap
之类的映射功能将一个请求的结果映射到下一个请求。使用forkJoin
同时执行多个请求
因此,对于一对多方案,总体思路是:
firstRequest().pipe(
switchMap(results=>forkJoin(results.map(r=>nextRequest(r)))
)
对于您的情况,这将类似于:
use=[];
a、 获取('abc')。管道(
switchMap(abcdatas=>forkJoin(getUseFulRequests(abcdatas)),
轻触(有用=>有用的.forEach(u=>this.有用的.push(u)),
switchMap(有用=>use.length?c.get('ghi'):空)
).订阅((吉达)=>{
完整的。。。
});
函数getUseFulRequests(abcdatas:AbcData[]):Observable[]{
返回abcdata。减少((acc,abcdata)=>{
if(abcdata.exist){
const request=b.get('def')管道(
映射(defdatas=>defdatas.someval)
)
acc.push(请求);
}
返回acc;
}, []);
}
如果
getUseFulRequests(abcdatas)
返回空数组或Use.length==0
使用类似switchMap
或mergeMap
的映射函数将一个请求的结果映射到下一个请求,则不会发出任何消息。使用forkJoin
同时执行多个请求
因此,对于一对多方案,总体思路是:
firstRequest().pipe(
switchMap(results=>forkJoin(results.map(r=>nextRequest(r)))
)
对于您的情况,这将类似于:
use=[];
a、 获取('abc')。管道(
switchMap(abcdatas=>forkJoin(getUseFulRequests(abcdatas)),
轻触(有用=>有用的.forEach(u=>this.有用的.push(u)),
switchMap(有用=>use.length?c.get('ghi'):空)
).订阅((吉达)=>{
完整的。。。
});
函数getUseFulRequests(abcdatas:AbcData[]):Observable[]{
返回abcdata。减少((acc,abcdata)=>{
if(abcdata.exist){
const request=b.get('def')管道(
映射(defdatas=>defdatas.someval)
)
acc.push(请求);
}
返回acc;
}, []);
}
如果
getUseFulRequests(abcdatas)
返回空数组或use.length==0
我认为处理此问题的最佳方法是使用高阶可观测值
考虑下面的代码
useful$ = a.get('abc').pipe(
mergeMap(abcdatas =>
abcdata.exist ? forkJoin(abcdatas.map(abcdata => b.get('def'))) : of(undefined)
),
map(defdatas => defdatas.flat()),
mergeMap(({ length }) => length ? c.get('ghi') : of(undefined))
);
useful$.subscribe({
next: () => {
// Completed...
}
})
我们首先通过管道传输a.get('abc')
的结果,并使用mergeMap测试abcdata.exist
。如果它确实退出,我们将返回forkJoin(abcdatas.map(abcdata=>b.get('def'))
这将结合abcdatas上的map函数生成的观察值数组
map(defdatas=>defdatas.flat()),
将数组转换为单个数组
注意:在ES2019中引入了flat()
接下来,我们将分解
length
属性,如果它存在,我们将返回最终的可观测值我相信处理这个问题的最佳方法是使用高阶可观测值
考虑下面的代码
useful$ = a.get('abc').pipe(
mergeMap(abcdatas =>
abcdata.exist ? forkJoin(abcdatas.map(abcdata => b.get('def'))) : of(undefined)
),
map(defdatas => defdatas.flat()),
mergeMap(({ length }) => length ? c.get('ghi') : of(undefined))
);
useful$.subscribe({
next: () => {
// Completed...
}
})
我们首先通过管道传输a.get('abc')
的结果,并使用mergeMap测试abcdata.exist
。如果它确实退出,我们将返回forkJoin(abcdatas.map(abcdata=>b.get('def'))
这将结合abcdatas上的map函数生成的观察值数组
map(defdatas=>defdatas.flat()),
将数组转换为单个数组
注意:在ES2019中引入了flat()
接下来,我们将分解
length
属性,如果它存在,我们将返回我们的最终可观测值,我认为您要做的是:
a.get("abc").pipe(
mergeMap((abcdatas) => abcdatas.filter((abcdata) => abcdata.exist)), // let's create a stream with all those useful abcdata
mergeMap(abcdata => b.get('def')), // and for each one of those we perform a b.get request
toArray(), // once all the b.get requests have completed, emit a one value stream with an Array of those values values
concatMap(useful => useful.length ? c.get('ghi') : EMPTY) // let's concat that result with the final request
)
我认为你想做的是:
a.get("abc").pipe(
mergeMap((abcdatas) => abcdatas.filter((abcdata) => abcdata.exist)), // let's create a stream with all those useful abcdata
mergeMap(abcdata => b.get('def')), // and for each one of those we perform a b.get request
toArray(), // once all the b.get requests have completed, emit a one value stream with an Array of those values values
concatMap(useful => useful.length ? c.get('ghi') : EMPTY) // let's concat that result with the final request
)
感谢您的响应。有用的不仅仅是有用的请求,它是由第二次调用i形成的数组。b、 get()@MithunshreVatsa您可以使用
点击
从中间响应填充全局数组。例如,正如我所说的,我是新手,从axios和async出来需要时间,请等待并承诺谢谢,我从你的回答中学到了一些非常有用的东西,并给我打了一个明确的电话:)感谢你的回答。这不仅仅是对有用的请求,它是由第二次呼叫i形成的数组。b、 get()@MithunshreVatsa您可以使用点击
从中间响应填充全局数组。例如,正如我所说的,我是新手,从axios和async出来需要时间,请等待并承诺谢谢,我从你的回答中学到了一些非常有用的东西,并给我打了一个明确的电话:)感谢你的回答