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, e.g. using a
reduce
function to count a sum or an average. But I need to know all elements in order to calculate it. - array of click events. They e asynchronously (in future & I don't know how many and when they e).
Using the mon Observable
datatype I can perform many operations on different elements, such as merge
, zip
etc.
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 pleted? 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?
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 pleted.
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, e.g. using a
reduce
function to count a sum or an average. But I need to know all elements in order to calculate it. - array of click events. They e asynchronously (in future & I don't know how many and when they e).
Using the mon Observable
datatype I can perform many operations on different elements, such as merge
, zip
etc.
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 pleted? 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?
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 pleted.
Share Improve this question edited Sep 2, 2016 at 13:32 ducin asked Aug 19, 2016 at 7:03 ducinducin 26.5k44 gold badges166 silver badges261 bronze badges1 Answer
Reset to default 10As you already said, Rx will help you with async events. Sure in the case of reduce
you could also use the Array
method. 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.
So, if you're using RxJS it will basically do (b) for you. Meaning, that it will store the accumulated value in the observable created by the .reduce
method. Whenever a new value es along (from the producer) it will apply the methods again.
In case of count
, max
and min
: They are actually filter methods. Sure you could implement this with temporary values and some Array
methods. 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. The operators you mentioned are just a big toolkit to transform/filter/... ining things. I would suggest reading this article by 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 plete. So you have to do (a) or (b), which is really annoying. RxJS abstracts this behaviour for you, so you can deal with real problems.
About pletion
I missed one point you made about a sequence needs to be pleted:
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. 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./suqila/1/edit?js,output
In the non-RxJS you always have to store the state and introduce a side effect in your method. With RxJS you can remove the side effect which makes code much easier to reason about.
Sync vs. async
In the article I mentioned above Ben Lesh says:
Observables are usually async.
What he means by this is that you're usually using observables to cope problems that are async, autoplete is a very popular example. Rarely you can also use synchronous Observables. Observable.of([1,2,3])
is synchronous for example.
This might be confusing at first, but in reality it doesn't really matter. Observables are lazy/push-based. 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. That's pretty much it. They execute when a new value is pushed through the operator chain.