【问题标题】:How do I subscribe in sequence and return only the value from the last observable in RxJS?如何按顺序订阅并仅返回 RxJS 中最后一个 observable 的值?
【发布时间】:2019-10-18 21:45:51
【问题描述】:

我在一个 Angular 路由解析器中,想要返回一个 observable。

我需要按顺序订阅多个异步进程:

A => B(a) => C(b)

C 依赖于 B,B 依赖于 A。A 必须完成,然后是 B,然后是 C,但我只希望 C 中的值用于导致路由解析。

我尝试了两种不同的方法:

return A.pipe(
  concatMap(a => 
    B(a).pipe(
      concatMap(b => 
        C(b).pipe((c) => c); // also tried of(c)
      )
    )
  )
);

我也试过

return A.pipe(
  concatMap(a => {
    return B(a).pipe(map(b => {a: a, b: b});
  ),
  concatMap({a, b} => {
    return C(b);
  )
);

如何订阅 A,然后是 B,然后是 C ...,然后只从最里面的 observable 中获取值?

如果我在最后一个 concatMap 之后点击,我会得到预期的返回值。但是我的解析器永远不会解析? (或者发出了错误的东西?我真的不能说。)

【问题讨论】:

    标签: angular rxjs concatmap


    【解决方案1】:

    路由解析器需要在 Angular 路由器继续运行之前完成。路线守卫也是如此。添加一个接受发射的运算符,例如 take(1) 或 first() 并完成将解决问题。

    return A.pipe(
      concatMap(a => {
        return B(a).pipe(map(b => {a: a, b: b});
      ),
      concatMap({a, b} => {
        return C(b);
      ),
      take(1)
    );
    

    【讨论】:

    • 它可以工作,但是为什么当它是一个单独的 observable 时我不必使用任何像 take 这样的操作符?
    【解决方案2】:

    如果链中的一个 observable 从未完成(如路由参数或查询参数),它将停止整个火车。

    switchMap 应该这样做:

    A.pipe(
        switchMap(B), // which is more or less the same as `switchMap(a => B(a))`
        switchMap(C),
    ).subscribe(//...
    

    【讨论】:

    • B 需要 A 的值,C 需要 B 的值。当内部发出时,switchMap 不会停止外部吗?
    • B 得到 A 的输出,C 得到 B 的输出。你可以试试它是否有效,或者写一些关于所涉及的流的更多细节。
    • 我没有尝试您的答案,因为我从另一个来源得到了答案,说只需使用 take(1) 就可以满足我的需要。在某个地方,你的答案至少在这方面是正确的,我的一个可观察的没有完成。
    猜你喜欢
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 2021-04-22
    相关资源
    最近更新 更多