在rxjs中,将合并放置在switchmap与在switchmap之后放置合并有什么区别?

发布于 2025-02-04 15:30:53 字数 1239 浏览 4 评论 0原文

我不明白这两个代码之间的区别,我期望相同的行为。第一个在SwitchMap之后具有Groupby和Mergemap。第二个将它们放在SwitchMap中。

const arraySubject = new Subject();

arraySubject.pipe(
  switchMap((arr) => from(arr)),
  groupBy((elem) => elem.type),
  mergeMap((group) => group.pipe(toArray()))
).subscribe((arrGroups) => {
  // nothing gets logged
})

arraySubject.next([{name: 'Bill', type: 'user'}, {name: 'Jane', type: 'admin'}, {name: 'John', type: 'user'}, {name: 'Ann', type: 'admin'}])

现在,如果我将Groupby和Mergemap放在(ARR)的管道中,一切正常。

const arraySubject = new Subject();

arraySubject.pipe(
  switchMap((arr) => 
    from(arr).pipe(
      groupBy((elem) => elem.type),
      mergeMap((group) => group.pipe(toArray()))))
).subscribe((arrGroups) => {
  arrGroups === [
   {name: 'Bill', type: 'user'}, 
   {name: 'John', type: 'user'}
  ], [
   {name: 'Jane', type: 'admin'}, 
   {name: 'Ann', type: 'admin'}] //true
})

arraySubject.next([{name: 'Bill', type: 'user'}, {name: 'Jane', type: 'admin'}, {name: 'John', type: 'user'}, {name: 'Ann', type: 'admin'}])

在代码的第一个块中,我只是猜测groupby只需按类型进行分组,然后将两个可观察结果(在这种情况下)传递到合并中,然后将这两个可观察到的可观测值转换为一个数组。我认为第二件代码会做完全相同的事情吗?但是由于某种原因,第一个不起作用。为什么第一个不起作用,第二个不起作用?

I don't understand the difference between these two chunks of code, I would expect identical behavior. The first one has a groupBy and mergeMap after the switchMap. The second one has them inside the switchMap.

const arraySubject = new Subject();

arraySubject.pipe(
  switchMap((arr) => from(arr)),
  groupBy((elem) => elem.type),
  mergeMap((group) => group.pipe(toArray()))
).subscribe((arrGroups) => {
  // nothing gets logged
})

arraySubject.next([{name: 'Bill', type: 'user'}, {name: 'Jane', type: 'admin'}, {name: 'John', type: 'user'}, {name: 'Ann', type: 'admin'}])

Now if I put the groupBy and mergeMap in the pipe of the from(arr) everything works.

const arraySubject = new Subject();

arraySubject.pipe(
  switchMap((arr) => 
    from(arr).pipe(
      groupBy((elem) => elem.type),
      mergeMap((group) => group.pipe(toArray()))))
).subscribe((arrGroups) => {
  arrGroups === [
   {name: 'Bill', type: 'user'}, 
   {name: 'John', type: 'user'}
  ], [
   {name: 'Jane', type: 'admin'}, 
   {name: 'Ann', type: 'admin'}] //true
})

arraySubject.next([{name: 'Bill', type: 'user'}, {name: 'Jane', type: 'admin'}, {name: 'John', type: 'user'}, {name: 'Ann', type: 'admin'}])

In the first chunk of code I just guessed that groupBy would simply group the elements by type then pass two observables (in this case) to the mergeMap which will then convert those two observables to an Array. In my opinion the second piece of code would do the exact same thing? But for some reason the first one does not work. Why is the first one not working, and the second one working?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撩动你心 2025-02-11 15:30:53

这里的问题是您的arraysubject永远不会完成。因此,toarray()不知道何时发出收集的值。

在第二个示例中,来自(arr)是源(而不是主题),它确实完成,并让toarray()发射缓冲值。


更新01:

为什么从完整和Arraysubject中没有?到达数组末端时,是否可以完成?

简而言之:是的,正是这个。

有点扩展:

const numStream$ = from([1,2,3,4])

与(我说相似,因为一个“热”,而一个“冷”。如果没有人在发出时订阅该主题,则值是丢失的)。

const sub = new Subject<number>();
sub.next(1);
sub.next(2);
sub.next(3);
sub.next(4);
sub.complete();

也就是说,当您将数组传递到()>时,它将发出数组的每个元素,然后通过发射填写来发出整个数组的元素。

必须明确地完成一个主题,因为它不知道您是否打算继续发射(通过object.next())将来有一段时间。它必须假设它可能仍然可以获得一个值,直到明确告知它不会。

The issue here is that your arraySubject never completes. So toArray() doesn't know when to emit the collected values.

In the second example, from(arr) is the source (instead of the subject) which does complete and lets toArray() emit the buffered values.


Update 01:

Why does from complete and arraySubject does not? Does from just complete when it gets to the end of an array?

In short: yes, exactly this.

To expand on that a bit:

const numStream$ = from([1,2,3,4])

is the similar to (I say similar, since one is "hot" and one is "cold". If nobody is subscribed to the subject when it emits, the value is lost).

const sub = new Subject<number>();
sub.next(1);
sub.next(2);
sub.next(3);
sub.next(4);
sub.complete();

That is, when you pass an array to from(), it will emit each element of the array and then signal the the entire array's elements have been emitted by emitting a complete

A Subject must be completed explicitly, since it doesn't know if you plan to continue emitting (via subject.next()) some time in the future. It must assume it may still get a value until it's explicitly told that it will not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文