baconjs / bacon.js

Functional reactive programming library for TypeScript and JavaScript

Home Page:https://baconjs.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

flatMapLatest(Bacon.once) is unlike flatMap(Bacon.once)

semmel opened this issue · comments

It swallows startWith and mapEnd values:

expected behaviour

Calling .startWith or .mapEnd multiple times on a stream injects those values just fine in the right order:

Bacon.fromArray([1, 2, 3])
.startWith(-1)
.startWith(-2)
.mapEnd(10)
.mapEnd(11)
.flatMap(x => Bacon.once(x))
// -> -2, -1, 1, 2, 3, 10, 11

observed behaviour

Bacon.fromArray([1, 2, 3])
.startWith(-1) // <- missing after flatMapLatest(Bacon.once)
.startWith(-2)
.mapEnd(10) // <- missing after flatMapLatest(Bacon.once)
.mapEnd(11)
.flatMapLatest(x => Bacon.once(x))
// -> -2, 1, 2, 3, 11

I'd expect .flatMapLatest(Bacon.once) to behave like .flatMap(Bacon.once).

Somehow the following startWith and mapEnd events are delivered too quickly to allow Bacon.once to emit just it's only value.

Found a workaround: delay(0)!

Bacon.concatAll([
  Bacon.once(-2), 

  Bacon.fromArray([1, 2, 3])
  .startWith(-1)
  .mapEnd(10)
  .delay(0),    // <---

  Bacon.once(11)
])
.flatMapLatest(x => Bacon.once(x))
// -> -2, -1, 1, 2, 3, 10, 11

I guess the eagerness of Bacon streams is a problem;

const
  // source streams
  t1 = Bacon.once("foo"),
  t2 = Bacon.once("foo"),
  t3 = Bacon.once("foo"),
  // derived streams
  d1 = t1
    .map(s => s.toUpperCase())
    .startWith("zero"),
  d2 = t2
    .map(s => s.toUpperCase()),
  d3 = t3
    .map(s => s.toUpperCase())
    .startWith("zero");

d1.onValue(val => { console.log("d1:", val); });
// -> "zero", "FOO", <end>    (Great!)

t2.onValue(() => {});
d2.onValue(val => { console.log("d2:", val); });
// -> "FOO", <end>   (Great!)

t3.onValue(() => {});
d3.onValue(val => { console.log("d3:", val); });
// -> "zero", <end>    (WTF??!)

It shows that e.g. Bacon.once breaks referential transparency. I think with lazy reactive streams you can have referential transparency.