对于同步和异步运算符和序列之间的区别,我有一个非常基本的问题。
我们在程序中处理的所有内容都可能表示为序列。这意味着我可以同时拥有:
reduce
函数计算总和或平均值。但我需要知道所有元素才能计算出来。使用通用Observable
数据类型,我可以对不同的元素执行许多操作,例如merge
,zip
等。
RxJS的整个想法是以异步方式处理序列,所以我的问题是 - 所有average,count,{{3需要序列完成的},max,min等运算符?如果我不能在序列中添加任何元素(异步添加元素到数组 - 为什么不呢?)以便重新计算 - 为什么我应该使用RxJS而不是Array.prototype.reduce?
换句话说 - 最初我认为序列应始终能够在其上执行运算符(whateevr运算符)当序列未完成时。
答案 0 :(得分:9)
正如您所说,Rx将帮助您处理异步事件。当然,在reduce
的情况下,您也可以使用Array
方法。但是你必须(a)从一开始就进行整个计算,当新值到达时或(b)存储累计值并对新值进行单一减少。
所以,如果你正在使用RxJS,它基本上会(b)为你做。意思是,它将累积的值存储在.reduce
方法创建的observable中。每当出现一个新值(来自生产者)时,它将再次应用这些方法。
如果是count
,max
和min
:它们实际上是过滤方法。当然,您可以使用临时值和一些Array
方法来实现此功能。但是,如果你自己已经尝试过,那么实现和处理异步事件真的很麻烦。您必须存储临时值,...
RxJS将为您抽象出所有的异步。您提到的运算符只是转换/过滤/传入内容的重要工具包。我建议阅读this article by Ben Lesh。
RxJS的最大胜利在于,特别是如果你正在构建一个用户界面,你永远都不会知道你的同步数据" (=事件)完成。所以你必须做(a)或(b),这真的很烦人。 RxJS为您抽象出这种行为,因此您可以处理实际问题。
我错过了一个关于序列需要完成的观点:
对所有运营商而言并非如此。如果您订阅了Observable +操作链,您将始终获得由observable生成的当前(= last)值。如果通过管道推送新值,则将更新当前值并通知所有订户。
这是一个非常简单的例子,在我看来,为什么RxJS比旧的做事方式有了很大的改进":http://jsbin.com/suqila/1/edit?js,output
在非RxJS中,您始终必须存储状态并在方法中引入副作用。使用RxJS,您可以消除副作用,使代码更容易推理。
在我上面提到的文章中,Ben Lesh说:
Observable 通常是异步。
他的意思是你通常使用observable来处理异步问题,自动完成是一个非常流行的例子。您很少使用同步Observable。例如,Observable.of([1,2,3])
是同步的。
起初这可能令人困惑,但实际上它并不重要。 Observable是 lazy / push-based 。意思是,他们什么都不做,直到他们从他们的制作人和/或订阅他们的人那里推出一个新的价值(取决于他们是热还是冷)。但是,如果进程是同步的或异步的,它取决于生产者。
运营商也是如此。它们是获取源可观察对象的函数,并返回一个新的observable,当您订阅它时,它将订阅该源可观察对象。几乎就是这样。它们在通过运营商链推送新值时执行。