微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

RXJS - 嵌套 concapMap 是否等同于顺序 concatMap? 示例

如何解决RXJS - 嵌套 concapMap 是否等同于顺序 concatMap? 示例

当使用 RXJS 时,我问自己嵌套的 concatMap 是否等同于顺序的。考虑以下示例:

observable1.pipe(
   concatMap(result1 => observable2.pipe(
      concatMap(result2 => observable3.pipe(
         concatMap(result3 => of(result3)
      )
   )
).susbcribe((result) => {...});

这将导致 resultresult3。为了避免嵌套,我想这样写:

of(null).pipe(
   concatMap(() => observable1),concatMap(result1 => observable2),concatMap(result2 => observable3),concatMap(result3 => of(result3))
).susbcribe((result) => {...});

这将导致 result 也成为 result3。即使在细节层面上可能存在差异,我是否可以假设连接 observable 的两种方式都被认为是等效的(例如,在失败方面)?

感谢任何帮助...

解决方法

不,它们的行为方式并非在所有情况下都相同。

嵌套 ConcatMap

observable1.pipe(
  concatMap(result1 => inner2)
)

inner2 = observable2.pipe(
  concatMap(result2 => observable3.pipe(
    concatMap(result3 => of(result3))
  ))
))

当前一个 observable1 observable 完成时,会将下一个值从 inner2 映射到 inner2

顺序 ConcatMap

observable1.pipe(
  concatMap(result1 => observable2),concatMap(result2 => observable3),concatMap(result3 => of(result3))
)

将在前一个 observable1 完成时将下一个值从 observable2 映射到 observable2

您在最终订阅回调中收到的结果将是相同的,并且会以相同的顺序到达。但是您收到这些结果的时间可能会有所不同,因为 Nested ConcatMap 中的 observable 可能会比 Sequential ConcatMap 中的 observable 映射到后续的 inner2 observable 晚映射到后续的 observable2 可观察对象,因为 inner2 可能需要比 observable2 更长的时间才能完成。

示例

使用三个可观察值 obs_1obs_2obs_3 的事件以何种顺序发生的示例:https://stackblitz.com/edit/rxjs-mxfdtn?file=index.ts

使用嵌套 ConcatMap obs_2obs_3 是同一个内部可观察对象 (inner2) 的一部分,因此第二个 inner2 仅在第一个 {{1} 之后订阅}}(包含第一个 inner2、第一个 obs_2、第二个 obs_3)已完成。使用 Sequential ConcatMap,一旦第一个 obs_3 完成,就会订阅第二个 obs_2

obs_2
obs_1: --11--12|
obs_2: --21--22|
obs_3: --31--32|

// Nested ConcatMap
   ❶
--11--12|~~~~~~~~~~~~~~~~~12
   │                       └--21--22|~~~22
   │                           │         └--31--32|
   │        ❷             ❸    └--31--32|
   └--21--22|~~~22        |
       │         └--31--32|    
       └--31--32|              

output: --31--32----31--32--------31--32----31--32|


// Sequential ConcatMap
   ❶
--11--12|~~~12
   │         └--21--22|~~~21~~~~~~~~22
   │                       │         └--31--32|
   │        ❷              └--31--32|
   └--21--22|~~~22        ❸
       │         └--31--32|
       └--31--32|

output: --31--32----31--32----31--32----31--32|


x~~~x    x is emitted at the first position but concatMap is holding the value 
    └O   back and waits with ~ until a previous observable completes and then 
         maps the value to the observable O.

正如您所看到的,Sequential ConcatMap 方法比 Nested ConcatMap 方法更早订阅了第二个 ❶ start of the 1st obs_2. For Nested ConcatMap this also marks the start of the 1st inner2. ❷ The 1st obs_2 completed but the 1st inner2 hasn't completed yet. Nested ConcatMap waits until the 1st inner2 completes before it maps 12 to the 2nd inner2. Sequential ConcatMap will map 12 to the 2nd obs_2 straight away. ❸ The 1st inner2 completed. Nested ConcatMap maps 12 to the 2nd inner2. Sequential ConcatMap has already mapped 12 to the 2nd obs_2 by this time and this 2nd obs_2 has already emitted both values and completed but concatMap has buffered those values until now. observable。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。