My strategy is outlined below:
src$ = src$.pipe(publish());
const wholeNumber$ = src$.pipe(
scan(
(acc, crt) => (acc | 0) > 1 ? crt + (+(acc - (acc | 0)).toPrecision(1)) : acc + crt, 0
),
map(v => (v | 0)),
filter(v => v >= 1),
);
src$.pipe(
buffer(wholeNumber$)
).subscribe();
publish
ensures that the source isn't subscribed to multiple times. It's essentially a condensed version of multicast(new Subject())
, which allows for multicasting a source. For this setup to function as intended, src$
needs to emit asynchronously so that the appropriate subscribers (wholeNumber$
and others) are registered by the Subject
.
In situations where the source doesn't emit asynchronously, you can make it do so by utilizing
src$.pipe(observeOn(asapScheduler))
, which schedules each notification as a promise.
Let's dissect the callback passed to scan
:
(acc, crt) => (acc | 0) > 1 ? crt + (+(acc - (acc | 0)).toPrecision(1)) : acc + crt`
The expression number | 0
is equivalent to Math.trunc(number)
.
Exploring
+(acc - (acc | 0)).toPrecision(1)
:
- For instance, performing
1.2 - 1
yields: 0.199...96
; with toPrecision(1)
: (1.2 - 1).toPrecision(1)
= "0.2"
. Applying +
turns 0.2
into a number.