RxJS 操作符 scan 与 reduce 的区别

阅读时长 4 分钟读完

在 RxJS 中,scan 和 reduce 都是处理 Observable 数据流的操作符,它们可以用来逐步计算 Observable 的结果。但是,它们之间也有一些不同之处,本文将深入介绍和比较它们的区别。

reduce

reduce 操作符可以将 Observable 发射的数据流中的数据,按照自定义的函数进行聚合。具体来说,reduce 接收两个参数:

其中,accumulator 是一个函数,用来将每个 emitted 数据和之前的结果合并;seed 是一个可选的初始值,作为一个历史值。

我们可以通过一个简单的示例来看看 reduce 的使用:

在这个示例中,我们使用了 interval 创建了一个每秒发送一次的数据流,然后使用 reduce 这个操作符,将这些发射的数据逐步累加并输出。最终,我们会得到输出:0, 1, 3, 6, 10, 15, 21, ...,它们表示了从 0 开始,每秒累加一个数的结果。

从这个例子中我们可以看到,reduce 将过去所有的值存储在 accumulator 中,并在每个值发射时更新这个值。这就是 reduce 和 scan 的关键区别。

scan

scan 用法和 reduce 非常相似,它也是将 Observable 中的每个数据都与前面的结果一起聚合。但是它们有一个显著的不同:scan 会为每个聚合结果都发出一个新的 Observable。

和 reduce 一样,scan 也需要一个函数作为参数,用于每个发射值的聚合计算。这个函数的第一个参数是 accumulator,它表示当前的中间值。第二个参数是当前发射的值。和 reduce 不同的是,第一个值不是初始值而是 source observable 发射的第一个值。因此,和 reduce 相比,scan 可以得到每个中间值。

下面是一个示例:

在这个示例中,我们同样使用 interval 这个函数创建一个每秒发射一个数字的 Observable。使用 scan 订阅这个 Observable,并将每个数字逐步累加,并发出每个中间值。

输出结果为:0, 1, 3, 6, 10, 15, 21, ...,这个结果和我们使用 reduce 得到的结果完全一样。

但是,我们可以使用 scan 更多的功能。比如:

在这个示例中,Observable 发出了一个数组,使用 scan 对这个数组进行累加,最终发出所有中间结果的数组。输出结果:[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4]。

总结

无论是使用 reduce 还是 scan,对于一个 Observable 的聚合都是很方便的。reduce 与 scan 的不同之处在于,reduce 替换掉了中间值,只发出最后的结果,而 scan 则是为每一个中间值都发出一个结果。因此,一般来说,如果我们更关心每一次聚合的结果,使用 scan;如果我们只关心最后的结果,使用 reduce。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e09e2bf6b2d6eab3bbd621

纠错
反馈