RN
Reactive Programming Library for TypeScript
glitch-less & hot Observable only RxJS
Usage
npm install rxjs rnjs
import { RN, interval } from 'rnjs'
const a: RN<number> = interval(1000, true);
a.subscribe( console.log );
features
-
glitch-less
const a = interval(1000);
const b = a.pipe( map( x => 100 * x ) );
const c = combineLatest( a, b ).pipe( map( ([x, y]) => x + y ) );
c.subscribe( console.log );
const a = interval(1000, true);
const b = a.map( x => 100 * x );
const c = combine( a, b ).map( ([x, y]) => x + y );
c.listen( true, console.log );
- about "glitch"
- all tasks are processed by the priority-queue
-
initial value
- all RNs have initial values
- you can get the current value with
value
property
(like BehaviorSubject
in RxJS)
import { RN, interval } from 'rnjs'
const a: RN<number> = interval(1000, true).take(8);
a.subscribe( console.log );
setTimeout( () => console.log( a.value ), 3500 );
setTimeout( () => console.log( a.value ), 5500 );
-
hot-RN(Observable) only
- no cold/hot conversion is necessary
- all subscribers of the RN receive the same value at the same time
-
compatiblity with RxJS
- mutual conversion methods (toObservable, fromObservable)
- the same
subscribe
API as RxJS
- RN can be passed to Angular async pipe
without conversion to RxJS Observable
Coresspondence tables to RxJS
RN | RxJS v6 |
---|
interval | interval |
fromEvent | fromEvent |
fromPromise | from |
fromObservable | - |
manual | BehaviorSubject |
- | ... |
RN | RxJS v6 |
---|
combine | combineLatest |
merge | merge |
- | concat |
- | zip |
- | ... |
RN | RxJS v6 |
---|
auditTime | auditTime |
delay | delay |
debounce | debounceTime |
filter | filter |
flatMap | flatMap |
map | map |
mapTo | mapTo |
pairwise | pairwise |
pluck | pluck |
scan | scan |
skip | skip |
skipAlreadyAppeared | distinct |
skipUnchanged | distinctUntilChanged |
skipWhile | skipWhile |
startWith | startWith |
switchMap | switchMap |
take | take |
takeWhile | takeWhile |
throttle | throttle |
withLatest | withLatestFrom |
withTimestamp | timestamp |
withInitialValue | - |
- | ... |
Examples
import { interval, combine, map } from 'rnjs';
const a = interval(100, true);
const b = a.pipe( map( x => 100 * x ) );
const c = combine( a, b ).map( ([x, y]) => x + y );
c.subscribe( console.log );
import { interval, combine } from 'rnjs';
const a = interval(100, false);
const b = a.map( x => 100 * x );
const c = combine( a, b ).map( ([x, y]) => x + y );
c.listen( true, console.log );
a.start();
- map (with index)
- index is initialized by
- map function receives
- source RN value
- source RN index (optional)
- this.index (optional)
- in the next example,
a
starts before b
is generated
--> a.index is not equal to b.index.
const a = interval(100, true);
const b = a.map( (sv, si, i) => [100 * sv, si, i] );
b.listen( true, console.log );
const a = interval( 100, false );
const b = a.withInitialValue(999)
b.listen( true, console.log );
a.start();
const a = interval( 100, false );
const b = a.delay( 50 ).map( x => 100 * x );
const c = merge( a, b );
c.listen( false, console.log );
a.start();
import { interval } from 'rnjs';
const a = interval(100, true);
const b = a.filter( 0, e => e % 10 < 5 );
const c = b.debounce(300);
b.listen( false, console.log );
c.listen( false, e => console.log( e, 'debounce') );
const a = interval( 100, false );
const b = a.filter( 0, x => x % 10 < 5 ).throttle( 250 );
b.listen( false, console.log );
a.start();
import { interval } from 'rnjs';
const a = interval(100, true);
const b = a.scan( [] as number[], (prev, curr) => {
prev.push( curr );
return prev;
});
a.listen( true, e => console.log('a', e ) );
b.listen( true, e => console.log('b', e ) );
import { interval, merge } from 'rnjs';
const a = interval(1000, false);
const b = interval(1000, false);
const c = b.map( e => 100 * e );
const d = merge( a, c );
a.start();
setTimeout(() => { b.start(); }, 500);
d.listen( true, console.log );
import { interval } from 'rnjs';
interval(100, true).pairwise()
.listen( true, console.log );
import { interval } from 'rnjs';
const a = interval(100, true);
const b = a.pairwise()
.map( e => ({ prev: e[0], curr: e[1] }) )
.pluck('curr');
b.listen( true, console.log );
const a = interval(100, true);
const b = a.take(5);
b.listen( true, console.log );
const a = interval(100, true);
const b = a.skip( 999, 3 );
b.listen( true, console.log );
- takeWhile, skipAlreadyAppeared
import { interval } from 'rnjs';
const values = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9];
const a = interval(100, false);
const b = a.map( (_sv, _si, i) => values[i] )
.takeWhile( (_sv, _si, i) => 0 <= i && i < values.length )
.skipAlreadyAppeared();
b.listen( false, console.log );
a.start();
const values = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9];
const a = interval(100, true);
const b = a.map( (_sv, _si, i) => values[i] )
.takeWhile( (_sv, _si, i) => 0 <= i && i < values.length )
.skipAlreadyAppeared();
b.listen( false, console.log );
const values = [3, 3, 3, 1, 4, 1, 5, 9, 9, 9, 2, 6];
const a = interval(100, true);
const b = a.map( (_sv, _si, i) => values[i] )
.takeWhile( (_sv, _si, i) => 0 <= i && i < values.length )
.skipUnchanged();
b.listen( false, console.log );
const a = interval(300, true);
const b = interval(100, true);
const c = a.withLatest( b );
c.listen( true, console.log );
const a = interval(300, true);
const b = a.withTimestamp();
b.listen( true, console.log );
const a = interval( 500, true );
const b = a.valueIs(3);
combine(a, b).listen( true, console.log )
const a = interval( 500, true );
const b = a.valueIsNot(3);
combine(a, b).listen( true, console.log )
const a = interval(1000, true);
const b = a.switchMap( x => interval(300, true).mapTo(x) );
b.listen( true, console.log );
const a = interval(1000, true);
const b = a.flatMap( x => interval(300, true).mapTo(x) );
b.listen( true, console.log );
const counter = interval( 500, true );
const a = counter.map( x => x % 2 === 0 );
const b = counter.map( x => x % 3 === 0 );
counter.listen( true, console.log );
every(a, b).listen( true, console.log );
const counter = interval( 500, true );
const a = counter.map( x => x % 2 === 0 );
const b = counter.map( x => x % 3 === 0 );
counter.listen( true, console.log );
some(a, b).listen( true, console.log );
const a = interval( 500, true ).take( 5 );
const pr = a.toPromise();
a.listen( true, console.log );
pr.then( v => console.log('resolve', v ) );
const a = interval( 500, true ).take( 5 );
const ob = a.toObservable();
a.listen( true, v => console.log('listen', v) );
ob.subscribe( v => console.log('subscribe', v ) );
const a = interval( 1000, true ).take( 5 );
a.listen( true, console.log );
setTimeout( () => a.once().then( v => console.log('once', v ) ), 2500 );
ToDo
- GUI application for generating RN code from data-flow graph
- add operators