RxJS中的同步序列与异步序列

duc*_*cin 6 javascript asynchronous rxjs

我有一个非常基本的问题,关于同步和异步运算符和序列之间的区别.

我们在程序中处理的所有内容都可以表示为序列.这意味着我可以同时拥有:

  • 作为序列的数字数组.这是我传统上同步处理的事情,例如使用reduce函数计算总和或平均值.但我需要知道所有元素才能计算出来.
  • 点击事件的数组.它们是异步的(将来我不知道有多少以及何时来).

使用公共Observable的数据类型我可以在不同的元素执行许多操作,例如merge,zip

RxJS的整个想法是以异步方式处理序列,所以我的问题是 - 所有平均值,计数,最大值,最小值,减少等运算符的重点什么,需要序列完成?如果我不能在序列中添加任何元素(异步添加元素到数组 - 为什么不呢?)以便重新计算 - 为什么我应该使用RxJS而不是Array.prototype.reduce?

换句话说 - 最初我认为序列应该始终能够在序列未完成时对其执行运算符(运算符为whateevr).

Seb*_*ald 10

正如您已经说过的,Rx将帮助您处理异步事件.当然,reduce你也可以使用这种Array方法.但是你必须(a)从一开始就进行整个计算,当新值到达时或(b)存储累计值并对新值进行单一减少.

所以,如果你使用的是RxJS,它基本上会为你做(b).意思是,它将累积的值存储在.reduce方法创建的observable中.每当出现一个新值(来自生产者)时,它将再次应用这些方法.

在情况下count,maxmin:他们实际上是过滤器的方法.当然你可以用临时值和一些Array方法来实现它.但是,如果你自己已经尝试过,那么实现和处理异步事件真的很麻烦.你必须存储临时值,...

RxJS将为您抽象出所有的异步.您提到的运算符只是转换/过滤/传入内容的重要工具包.我建议读Ben Lesh的这篇文章.

RxJS的最大胜利在于,尤其是在构建UI时,您永远不知道"异步数组"(=事件)何时完成.所以你必须做(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])例如是同步的.

这一开始可能会令人困惑,但实际上并不重要.Observables是懒惰/基于推送的.意思是,他们什么都不做,直到他们从他们的制作人和/或订阅他们的人那里推出一个新的价值(取决于他们是热还是冷).但是,如果进程是同步的或异步的,它取决于生产者.

运营商也是如此.它们是获取源可观察对象的函数,并返回一个新的observable,当您订阅它时,它将订阅该源可观察对象.这就是它.它们在通过运营商链推送新值时执行.