提问人:devguy 提问时间:11/18/2021 更新时间:11/19/2021 访问量:1740
仍然不明白RXJS运算符combineLatestAll是如何工作的?
Still don't understand how RXJS operator combineLatestAll works?
问:
我编写了以下示例,但仍然无法理解输出!
import { combineLatestAll, of, map } from 'rxjs';
const s1 = of(1, 2, 3).pipe(
map(v1 =>
of(100, 101, 102, 103, 104).pipe(
map(v2 => [v1,v2])
)
),
combineLatestAll()
);
s1.subscribe(console.log);
输出为:
[ [ 1, 104 ], [ 2, 104 ], [ 3, 100 ] ]
[ [ 1, 104 ], [ 2, 104 ], [ 3, 101 ] ]
[ [ 1, 104 ], [ 2, 104 ], [ 3, 102 ] ]
[ [ 1, 104 ], [ 2, 104 ], [ 3, 103 ] ]
[ [ 1, 104 ], [ 2, 104 ], [ 3, 104 ] ]
我已经看了很久的输出,但仍然无法理解这个运算符的行为。
答:
8赞
Pankaj
11/19/2021
#1
在您了解之前,我们先来分析一下 .combineLatestAll
combineLatest
根据此处显示的大理石图,如果我们有 2 个数据流,则“组合”来自 2 个流的最新值。combineLatest
这意味着,在它订阅的 2 个流中,除非它们都开始发出数据,否则您将看不到任何输出。
但是,如果第一个流在第二个流开始时已经完成,会发生什么。
var c1 = of(5, 15, 25);
var c2 = of(6, 16, 26);
var s2 = combineLatest([c1,c2]);
s2.subscribe(console.log) // Outputs = [25,6] [25,16] and [25, 26]
在这种情况下,运算符将从 source1 中获取最新/最后一个值(在上面的示例中为 25),然后在第二个流开始时开始发出输出(将来自 source1 的最新/最后一个值和来自 source2 的所有传入值组合在一起)combineLatest
如果,有 3 个来源。
在这种情况下,只有当所有 3 个流都开始生成输出时,才会产生输出。combineLatest
var c1 = of(5, 15, 25);
var c2 = of(6, 16, 26);
var c3 = of(7, 17, 27);
var s2 = combineLatest([c1,c2, c3]);
s2.subscribe(console.log) // Outputs = [25,26, 7] [25,26, 17] and [25, 26, 27]
在上述情况下,当第三个可观察对象开始发出该值时,其他两个可观察对象已经完成。因此,输出类似于从前 2 个源中获取最新/最后一个值,然后将其与第三个可观察对象中的所有值组合在一起。
上面的例子也可以写成——
var s3 = of(c1, c2, c3).pipe(combineLatestAll());
s3.subscribe(console.log);
在您最初的问题中,您看到的是完全相同的行为。前 2 个可观察对象具有最新值,然后它与最后一个可观察对象中的每个值组合在一起。
评论
0赞
devguy
11/21/2021
感谢您的明确解释。最后,我回到了“combineLatest”的定义,因为我的困惑集中在每个流如何发出值上。您的示例很容易确定输出,我也这样做了,但正如您从我的输出中可以清楚地看到的那样,并不总是使用任一流的最后一个值。在不运行我的代码的情况下,我仍然不清楚流是如何组合以生成输出的。
0赞
devguy
11/21/2021
好的,我又看了一眼,是地图让我失望了,我试着再次查看我的代码示例,看看流是如何播放的!
0赞
Abhishek
9/18/2023
感谢您的回答和问题,尽管我仍然不清楚两件事: 1.当没有任何延迟地使用运算符时,为什么变量 c2 或 c3 没有发出最后的值,而是从头开始发出。2. 在 devguy 提出的问题中,输出显示 [3,100] 尽管前两次发射是 104,但 100 是如何发出的
评论