【问题标题】:How do I chain together 2 forkJoins so the second call can use the data from the first?如何将 2 个 forkJoins 链接在一起,以便第二个调用可以使用第一个调用的数据?
【发布时间】:2022-06-14 03:52:38
【问题描述】:

我需要能够将 2 个 forkJoins 链接在一起,因为第二组 observables 需要第一组 observables 的输出。

问题是,如果我在 .pipe(map(...)) 内执行第二个,observable 将返回另一个 observable,而不是先解析组 1,然后再解析组 2。这意味着我必须在 subscribe 中有一个 subscribe 和两个单独的错误处理程序像这样。

var o = forkJoin(
    a: getObservableA(),
    b: getObservableB(),
    c: getObservableC()
).pipe(
    map( result => {
        a2: processA(result.a),
        b2: processB(result.b),
        c2: processC(result.c)
    }); 
)

o.subscribe( x => {
    x.subscribe( y => { 
        // It worked, process output {a2:..,b2... etc
    }, errorY => {... errors for part 2 })
}, errorX => {... errors for part 1 })

我也试过了:

forkJoin(
    a: getObservableA().pipe(map(processA(result.a)),
    b: getObservableB().pipe(map(processB(result.b)),
    c: getObservableC().pipe(map(processC(result.c))
).subscribe( x => ... )

但这给出了一个像 Observable<{a: Observable, b: Observable, c: Observable}> 这样的对象,这意味着这些 processX 调用没有被订阅和执行。

我真的不需要来自任何可观察对象的数据,只是为了获取第 1 组中的数据并在第 2 组中使用它。

有没有一种方法可以轻松地将两个 forkJoin 链接在一起,这样可以让一个错误处理程序来捕获任何错误并避免嵌套订阅,我被告知这是一种不好的模式?

【问题讨论】:

    标签: typescript rxjs


    【解决方案1】:

    也许您需要switchMap

    forkJoin([
      getObservableA(), 
      getObservableB(), 
      getObservableC()
    ]).pipe(switchMap(([r1, r2, r3]) => {
      return forkJoin([
        processA(r1), 
        processB(r2), 
        processB(r3)
      ])
    })).subscribe(([r1, r2, r3]) => {
      
    })
    

    最好在第一个forkJoin 内的每个元素之后直接调用processA/B/C

    forkJoin([
      getObservableA().pipe(switchMap(processA)), 
      getObservableB().pipe(switchMap(processB)), 
      getObservableC().pipe(switchMap(processC))
    ]).subscribe(([r1, r2, r3]) => {
    
    })
    

    这会更快,因为我们不必等待所有 Observable 完成后再开始处理它们。


    然后,您可以使用catchError()pipe() 中放置所有错误的错误处理程序。

    forkJoin([
      getObservableA().pipe(switchMap(processA)), 
      getObservableB().pipe(switchMap(processB)), 
      getObservableC().pipe(switchMap(processC))
    ]).pipe(catchError(err => {
      
    })).subscribe(([r1, r2, r3]) => {
    
    })
    

    或者,将它放在subscribe() 回调中。

    forkJoin([
      obs1.pipe(switchMap(processA)), 
      obs2.pipe(switchMap(processB)), 
      obs3.pipe(switchMap(processC))
    ]).subscribe(([r1, r2, r3]) => {
    
    }, error => {
      
    })
    

    【讨论】:

    • 我需要一个 switchMap!非常感谢您抽出宝贵时间写出如此出色的答案!
    猜你喜欢
    • 2018-06-05
    • 2021-05-13
    • 2014-07-25
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多