How does Observables (Rx.js) compare to ES2015 generators?

Observables push changes, and hence the observable, not the function reacting to it, is in control. Generators on the other hand require you to pull values out of them. So the function that will react to the new value determines when it is ready for a new value.

I had trouble with backpressure using observables, but with generators, you can let values out as slowly as you want.

Edit: the last question. Promises are just observables that only emit once, so I don’t think they will compete with each other. I think the real battle will be async/await vs observables, and async/await has a head start, and is already in C# (and now Node.js). But observables have that sweet FRP feel, and functional programing is super cool, so I think they will both end up with a good chunk of mindshare.

Edit2: André Staltz, author of Cycle.js and xstream, and contributor to Rx.js, wrote a great article on how generators and Observables relate (on 2018-01-31). In particular, he shows how they both inherit from a common base class.

And now a consumer can be a Listener (“observer”) or a Puller, it’s up to the consumer whether it will pull the producer or not. And the producer can be a Listenable (“observable”) or a Pullable (“iterable”), it’s up to the producer whether it sends data proactively or only on demand. As you can see, both consumer and producer are simple functions of the same type:

(num, payload) => void

So any operator that we build will work for both reactive programming or iterable programming, simply because the line between those two modes gets blurred and it’s not anymore about observables versus iterables, it’s just about transformations of data between producer and consumer.

I recommend reading it https://stackoverflow.com/questions/41349033/how-does-observables-rx-js-compare-to-es2015-generators. The article introduces “Callbags”, a spec for callbacks used for reactive and iterable programming. He implements that spec to make a tiny library for both iterable and reactive programming. To entice you to read the article and check out the library, here are some examples from the 7kb lib based on the spec he introduces:

Reactive programming example

Pick the first 5 odd numbers from a clock that ticks every second, then start observing them:

const {forEach, interval, map, filter, take, pipe} = require('callbag-basics');

pipe(
  interval(1000),
  map(x => x + 1),
  filter(x => x % 2),
  take(5),
  forEach(x => console.log(x))
);

// 1
// 3
// 5
// 7
// 9

Iterable programming example

From a range of numbers, pick 5 of them and divide them by 4, then start pulling those one by one:

const {forEach, fromIter, take, map, pipe} = require('callbag-basics');

function* range(from, to) {
  let i = from;
  while (i <= to) {
    yield i;
    i++;
  }
}

pipe(
  fromIter(range(40, 99)), // 40, 41, 42, 43, 44, 45, 46, ...
  take(5), // 40, 41, 42, 43, 44
  map(x => x / 4), // 10, 10.25, 10.5, 10.75, 11
  forEach(x => console.log(x))
);

// 10
// 10.25
// 10.5
// 10.75
// 11

Leave a Comment