简体   繁体   English

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

[英]synchronous vs asynchronous sequences in RxJS

I've got a quite basic, I guess, question about the difference between sync and async operators and sequences. 我有一个非常基本的问题,关于同步和异步运算符和序列之间的区别。

Everything that we deal with in programs might be represented as a sequence. 我们在程序中处理的所有内容都可以表示为序列。 It means I can have both: 这意味着我可以同时拥有:

  • array of numbers as a sequence. 作为序列的数字数组。 It's something I would traditionally deal with synchronously, eg using a reduce function to count a sum or an average. 这是我传统上同步处理的事情,例如使用reduce函数来计算总和或平均值。 But I need to know all elements in order to calculate it. 但我需要知道所有元素才能计算出来。
  • array of click events. 点击事件的数组。 They come asynchronously (in future & I don't know how many and when they come). 它们是异步的(将来我不知道有多少以及何时来)。

Using the common Observable datatype I can perform many operations on different elements, such as merge , zip etc. 使用常见的Observable数据类型我可以对不同的元素执行许多操作,例如mergezip等。

The whole idea of RxJS is to treat sequences in an asynchronous manner, so my question is - what is the point of all average , count , max , min , reduce etc operators, which need the sequence to be completed? RxJS的整个想法是以异步方式处理序列,所以我的问题是 - 所有平均值计数最大值最小值减少等运算符的重点什么,需要序列完成? If I can't add any element into the sequence (asynchronously add element to an array - why not?) so that it re-calculates - why should I use RxJS over Array.prototype.reduce? 如果我不能在序列中添加任何元素(异步添加元素到数组 - 为什么不呢?)以便重新计算 - 为什么我应该使用RxJS而不是Array.prototype.reduce?

In other words - initially I thought that a sequence should always be capable of performing operators on it (whateevr the operators are) also when the sequence is not completed . 换句话说 - 最初我认为序列应该始终能够在序列未完成时对其执行运算符(运算符为whateevr)。

As you already said, Rx will help you with async events. 正如您已经说过的,Rx将帮助您处理异步事件。 Sure in the case of reduce you could also use the Array method. 当然,在reduce的情况下,您也可以使用Array方法。 But you would have to (a) do the whole calculate from the start, when a new value arrives or (b) store the accumulated value and do a single reduce on a new value. 但是你必须(a)从一开始就进行整个计算,当新值到达时或(b)存储累计值并对新值进行单一减少。

So, if you're using RxJS it will basically do (b) for you. 所以,如果你正在使用RxJS,它基本上会为你做(b)。 Meaning, that it will store the accumulated value in the observable created by the .reduce method. 意思是,它将累积的值存储在.reduce方法创建的observable中。 Whenever a new value comes along (from the producer) it will apply the methods again. 每当出现一个新值(来自生产者)时,它将再次应用这些方法。

In case of count , max and min : They are actually filter methods. countmaxmin情况下:它们实际上是过滤方法。 Sure you could implement this with temporary values and some Array methods. 当然,您可以使用临时值和一些Array方法实现此功能。 But, if you already tried this yourself, it is really cumbersome to implement and deal with async events. 但是,如果你自己已经尝试过,那么实现和处理异步事件真的很麻烦。 You have to store temporary values, ... 你必须存储临时值,...

RxJS will abstract all the async away for you. RxJS将为您抽象出所有的异步。 The operators you mentioned are just a big toolkit to transform/filter/... incoming things. 您提到的运算符只是转换/过滤/传入内容的重要工具包。 I would suggest reading this article by Ben Lesh . 我建议读Ben Lesh的这篇文章

The big win with RxJS is that, especially if you're building a UI, you never know when your "async array" (=events) is complete. RxJS的最大胜利在于,尤其是在构建UI时,您永远不知道“异步数组”(=事件)何时完成。 So you have to do (a) or (b), which is really annoying. 所以你必须做(a)或(b),这真的很烦人。 RxJS abstracts this behaviour for you, so you can deal with real problems. RxJS为您抽象出这种行为,因此您可以处理实际问题。

About completion 关于完成

I missed one point you made about a sequence needs to be completed: 我错过了一个关于序列需要完成的观点:

That is not true for all the operators. 对于所有运营商而言,情况并非如此。 If you subscribe to the Observable + operator chain you'll always get the current (=last) value produced by the observable. 如果您订阅Observable +运算符链,您将始终获得observable生成的当前 (= last)值。 If a new value is pushed through the pipeline the current value will be updated and all subscribers will be notified. 如果通过管道推送新值,则将更新当前值并通知所有订户。

Example

Here is a very very simple example that in my opinion shows why RxJS is such a huge improvement over the "old way of doing things": http://jsbin.com/suqila/1/edit?js,output 这是一个非常简单的例子,在我看来,为什么RxJS比“旧的做事方式”有了如此巨大的改进: http ://jsbin.com/suqila/1/edit?js,output

In the non-RxJS you always have to store the state and introduce a side effect in your method. 在非RxJS中,您始终必须存储状态并在方法中引入副作用。 With RxJS you can remove the side effect which makes code much easier to reason about. 使用RxJS,您可以消除副作用,使代码更容易推理。

Sync vs. async 同步与异步

In the article I mentioned above Ben Lesh says: 在我上面提到的文章中,Ben Lesh说:

Observables are usually async. Observable 通常是异步的。

What he means by this is that you're usually using observables to cope problems that are async, autocomplete is a very popular example. 他的意思是你通常使用observable来处理异步问题,自动完成是一个非常流行的例子。 Rarely you can also use synchronous Observables. 您很少使用同步Observable。 Observable.of([1,2,3]) is synchronous for example. Observable.of([1,2,3])例如是同步的。

This might be confusing at first, but in reality it doesn't really matter. 这一开始可能会令人困惑,但实际上并不重要。 Observables are lazy/push-based . Observables是懒惰/基于推送的 Meaning, they do nothing until they get pushed a new value from their producer and/or someone subscribed to them (depending if they're hot or cold). 意思是,他们什么都不做,直到他们从他们的制作人和/或订阅他们的人那里推出一个新的价值(取决于他们是热还是冷)。 But it depends on the producer if the process is synchronous or asynchronous. 但是,如果进程是同步的或异步的,它取决于生产者。

Same is true for the operators. 运营商也是如此。 They are functions that take a source observable and returns a new observable that will subscribe to that source observable when you subscribe to it. 它们是获取源可观察对象的函数,并返回一个新的observable,当您订阅它时,它将订阅该源可观察对象。 That's pretty much it. 这就是它。 They execute when a new value is pushed through the operator chain. 它们在通过运营商链推送新值时执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM