Ping
Reactives for the most part have a push logic rather than pull. That is, they emit a value when and only when one is available.
In some cases, it makes sense for a reactive to offer pull logic. For example a reactive that outputs the result of a function call. In ixfx, we call these reactives ‘pingable’. This means they have a ping()
function which makes the reactive emit a value.
When using ping()
note that all subscribers to the reactive get the produced value.
In-built operators that return a ‘pingable’ reactive:
In-built pingable sources:
Value to Ping
Rx.valueToPing will ‘ping’ a target reactive whenever a value is emitted from a source reactive. The values from the source do not flow to the target, just the timing of its values.
// Listen for clicksconst source = Rx.From.event(document, `click`);
// Pingable streamconst target = Rx.From.func(() => Math.random());
// Whenever the user clicks, `target` will be triggered,// returning a value on the new `r` reactiveconst r = Rx.valueToPing(source, target);
r.onValue(v => { // a value from 'target', produced every time there is a click.})
To support lazy execution, it’s important to subscribe to the reactive returned by valueToPing
and not target
.
You can also gate the values, to be selective when when to ping, based on the source value.
const r = Rx.valueToPing(source, target, { gate:(value) => { // Don't ping if event happens in corner if (value.x < 100 && value.y < 100) return false;
// Ping return true; }});
Timeout ping
Rx.timeoutPing will ping a reactive if it hasn’t emitted a value after some interval.
// Call 'ping()' on 'source' if it hasn't emitted anything for one secondRx.timeoutPing(source, { secs: 1 });
This can be useful for when using the Rx.interpolate operator. When composed into a flow using Rx.run
or Rx.writable
for example,
timeoutPing
relates to the source before it in the flow.
In this example, we interpolate to a random number every time there’s a click. The interpolation steps in 100ms intervals.
const rx = Rx.writable( Rx.From.number(0), Rx.Ops.interpolate({ amount: 0.1 }), Rx.Ops.timeoutPing({ millis: 100 }))
document.addEventListener(`click`, () => { rx.set(Math.random());})
rx.onValue(v => { // Do something with value});
timeoutPing
can be passed an AbortSignal to cancel its behaviour. This might be useful to stop the pinging when the interpolation reaches its final value.