baconjs / bacon.js

Functional reactive programming library for TypeScript and JavaScript
https://baconjs.github.io
MIT License
6.47k stars 331 forks source link

.withLatestFrom(later(1, "foo"), …) depends on JS runtime #803

Open semmel opened 1 year ago

semmel commented 1 year ago

B.later(1, "foo") is like B.later(0, "foo") but only when running in Node – as different from when running in browsers.

demo code:

const B = require('baconjs'),
   concat = (a, b) => a + b, 
   s = B.once('foo').withLatestFrom(B.later(1, 'bar'), concat);
// let it run
s.onValue(console.log)

For a nice surprise execute that in Node, e.g. from a project shell where baconjs is installed:

node -e "const B = require('baconjs'), concat = (a, b) => a + b, unsub = B.once('foo').withLatestFrom(B.later(1, 'bar'), concat).onValue(console.log)"
# -> foobar

whereas in browser dev tools there is no event output :

import('./node_modules/baconjs/dist/Bacon.mjs').then(m => { globalThis.B = m; });
var concat = (a, b) => a + b;
var unsub = B.once("foo")
.withLatestFrom(B.later(1, "bar"), concat)
.onValue(s => { console.log(`sampled: "${s}"`); })

I guess I have to treat synchronicity or atomic updates with a grain of salt. 🤔

kryptt commented 1 year ago

I'm bit by this as well withLatestFrom seems to be swallowing events around a potential "circular" dependency:


  const qUnavailable = Bacon.constant(true).flatMap(() =>
    qProp.map(query => query.attr === undefined)
  );

  const eventsSub = events
    .log("searchEvent")
    .holdWhen(qUnavailable)
    .log("searchQueryReady")
    .withLatestFrom(
      qProp.log("query"),
      (event, query) => ({
        event: event,
        query: query,
      })
    ).onValue();