为了账号安全,请及时绑定邮箱和手机立即绑定

如何将 RXJS 中的嵌套调用展平并最终调用最后一个调用?

如何将 RXJS 中的嵌套调用展平并最终调用最后一个调用?

FFIVE 2023-05-11 16:37:49
我们如何最好地压平下面的电话。RxJS 的新手,试图了解应该如何简化它。阅读 flatMap、forkJoin、switchMap 和 mergeMap,在下面没有找到正确的集成路径,也不确定在下面的场景中哪个是最好的。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... });}更新在这里更新我的问题并感谢所有回复。有用的是一个全局结果数组,在我的例子中应该从嵌套调用中填充。最后应该传递给最后一个调用。我正在尝试的步骤:a.get() => 返回数据b.get(adataset) => 如果数据集具有存在属性,则应为每个数据集执行请求,并填充稍后将使用的有用数组c.get(useful) => 应该触发并退出。
查看完整描述

3 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

switchMap使用类似或 的映射函数mergeMap将一个请求的结果映射到下一个请求。用于forkJoin同时执行多个请求。


所以对于一对多的场景,一般的想法是:


firstRequest().pipe(

  switchMap(results => forkJoin(results.map(r => nextRequest(r))))

)

对于你的情况,这将是这样的:


useful = [];


a.get('abc').pipe(

  switchMap(abcdatas => forkJoin(getUseFulRequests(abcdatas))),

  tap(useful => useful.forEach(u => this.useful.push(u))),

  switchMap(useful => useful.length ? c.get('ghi') : EMPTY)

).subscribe((ghidata) => {

  completed...

});



function getUseFulRequests(abcdatas: AbcData[]): Observable<SomeVal>[] {

  return abcdatas.reduce((acc, abcdata) => {

    if (abcdata.exist) {

      const request = b.get('def').pipe(

        map(defdatas => defdatas.someval)

      )

      acc.push(request);

    }

    return acc;

  }, []);

}

getUseFulRequests(abcdatas)如果返回一个空数组或 ,这将不会发出任何东西useful.length == 0。


查看完整回答
反对 回复 2023-05-11
?
茅侃侃

TA贡献1842条经验 获得超21个赞

我认为你正在尝试做的是:


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

)


查看完整回答
反对 回复 2023-05-11
?
万千封印

TA贡献1891条经验 获得超3个赞

我相信处理这个问题的最好方法是使用高阶可观察量


考虑下面的代码


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 来测试 if abcdata.exist。如果它确实退出,我们forkJoin(abcdatas.map(abcdata => b.get('def')))简单地返回这将组合从 abcdatas 上的 map 函数生成的可观察数组


map(defdatas => defdatas.flat()),将数组转换为单个数组 注意:flat() 是在 ES2019 中引入的


接下来我们解构这个length属性,如果它存在,我们返回我们最终的可观察对象


查看完整回答
反对 回复 2023-05-11
  • 3 回答
  • 0 关注
  • 442 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信