RN
Reactive Programming Library for TypeScript
glitch-less & hot Observable only RxJS
Usage
- installation
npm install --save rnjs
- import
; // generate RN a.subscribe console.log ; // 0// 1// 2// ...
features
-
glitch-less
- in RxJS
;;;c.subscribe console.log ;// 0// 1 <-- glitch// 101// 102 <-- glitch// 202// 203 <-- glitch// 303// 304 <-- glitch// 404// 405 <-- glitch// 505// ...- in RN
// RN;;;c.listen true, console.log ;// 0// 101// 202// 303// 404// 505// ...- about "glitch"
- RX GLITCHES AREN'T ACTUALLY A PROBLEM
- Bainomugisha, Engineer, et al. "A survey on reactive programming." ACM Computing Surveys (CSUR) 45.4 (2013): 52.
- all tasks are processed by the priority-queue
-
initial value
- all RNs have initial values
- you can get the current value with
value
property (likeBehaviorSubject
in RxJS)
;a.subscribe console.log ;// |0---1---2---3---4---5---6---7---|// ^setTimeoutconsole.log a.value , 3500 ; // 3// |0---1---2---3---4---5---6---7---|// ^setTimeoutconsole.log a.value , 5500 ; // 5 -
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
- Source RNs
RN | RxJS v6 |
---|---|
interval | interval |
fromEvent | fromEvent |
fromPromise | from |
fromObservable | - |
manual | BehaviorSubject |
- | ... |
- Combination methods
RN | RxJS v6 |
---|---|
combine | combineLatest |
merge | merge |
- | concat |
- | zip |
- | ... |
- Operators
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
- interval, combine, map
; ; // ^ // +--- true --> start immediately;;c.subscribe console.log ;// c.listen( true, console.log ); /* output0101202303404505...*/
; ; // ^ // +--- false --> start manually; // ^ // +--- all operators can be used without pipe method;c.listen true, console.log ; // ^ // +--- true --> get the first valuea.start; // start manually /* output0 <-- first value0101202303404505...*/
- 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 beforeb
is generated --> a.index is not equal to b.index.
;;b.listen true, console.log ; /*[ 0, 0, -1 ][ 100, 1, 0 ][ 200, 2, 1 ][ 300, 3, 2 ][ 400, 4, 3 ][ 500, 5, 4 ][ 600, 6, 5 ][ 700, 7, 6 ][ 800, 8, 7 ][ 900, 9, 8 ]*/
- withInitialValue
;b.listen true, console.log ;a.start; /*99901234567...*/ /*interval : 0 |0---1---2---3---4---5---6---7---8---9--withInitialValue : 999 |0---1---2---3---4---5---6---7---8---9--*/
- delay
;;;c.listen false, console.log ;a.start; /*001100220033004400550066007700*/ /*interval : 0 |0---1---2---3---4---5---6---7---8---9--delay : 0 |--0---1---2---3---4---5---6---7---8---9*/
- debounce, filter
; ;; // ^ // +--- filter requires initial value;b.listen false, console.log ;c.listen false, console.log e, 'debounce' ; /* output12344 'debounce'101112131414 'debounce'...*/ /*interval : 0 |0--1--2--3--4--5--6--7--8--9--10-11-12-13-14-15-16-17-18-19-filter : 0 |0--1--2--3--4-----------------10-11-12-13-14----------------debounce : 0 |---------------------4-----------------------------14-------*/
- throttle
;;b.listen false, console.log ;a.start; /*031013202330334043...*/ /*interval : 0 |0--1--2--3--4--5--6--7--8--9--10-11-12-13-14-15-16-17-18-19-filter : 0 |0--1--2--3--4-----------------10-11-12-13-14----------------throttle : 0 |0--------3--------------------10-------13-------------------*/
- scan
; ;;a.listen true, console.log'a', e ;b.listen true, console.log'b', e ; /* outputa 0b []a 1b [ 1 ]a 2b [ 1, 2 ]a 3b [ 1, 2, 3 ]*/
- merge
; ;;;;a.start;setTimeout, 500;d.listen true, console.log ; /* output0011002200330044005500*/ /*a : 0 |0-------1-------2-------3-------4-------5-------6-------b : 0 |0------100-----200-----300-----400-----500-----600-----c : 0 |0---0---1--100--2--200--3--300--4--400--5--500--6--600--*/
- pairwise
; interval100, true.pairwise .listen true, console.log ; /* output[ 0, 0 ][ 0, 1 ][ 1, 2 ][ 2, 3 ][ 3, 4 ][ 4, 5 ][ 5, 6 ][ 6, 7 ][ 7, 8 ]...*/ /*interval : 0 |0------1------2------3------4------5------6------pairwise : [0,0] |[0,0]--[0,1]--[1,2]--[2,3]--[3,4]--[4,5]--[5,6]--*/
- pluck
; ; .map .pluck'curr';b.listen true, console.log ; /* output0123...*/
- take
;;b.listen true, console.log ; /*01234*/
- skip
;; // ^ // +--- skip requires initial valueb.listen true, console.log ; /*9993456789*/ /*interval : 0 |0---1---2---3---4---5---6---7---8---9---10--11--12--...skip : 999 |----------3---1---4---1---5---9---2---6---u---u---...*/
- takeWhile, skipAlreadyAppeared
; ;; .takeWhile0 <= i && i < values.length .skipAlreadyAppeared;b.listen false, console.log ;a.start; /* output31459268*/ /*interval : 0 |0---1---2---3---4---5---6---7---8---9---10--11--12--13--14--...map : 3 |3---1---4---1---5---9---2---6---5---3---5---8---9---u---u---takeWhile : 3 |3---1---4---1---5---9---2---6---5---3---5---8---9---skipAlreadyAppeared : 3 |3---1---4-------5---9---2---6---------------8-------*/
;; .takeWhile0 <= i && i < values.length .skipAlreadyAppeared;b.listen false, console.log ; /* output31459268*/ /*interval : 0 |0---1---2---3---4---5---6---7---8---9---10--11--12--13--14--...map : ud |3---1---4---1---5---9---2---6---5---3---5---8---9---u---u---takeWhile : ud |3---1---4---1---5---9---2---6---5---3---5---8---9---skipAlreadyAppeared : ud |3---1---4-------5---9---2---6---------------8-------*/
- skipUnchanged
;; .takeWhile0 <= i && i < values.length .skipUnchanged;b.listen false, console.log ; /*31415926*/ /*interval : 0 |0---1---2---3---4---5---6---7---8---9---10--11--12--...map : ud |--3---3---3---1---4---1---5---9---2---6---u---u---...takeWhile : ud |--3---3---3---1---4---1---5---9---2---6---skipUnchanged : ud |--3-----------1---4---1---5---9---2---6---*/
- withLatest
;;;c.listen true, console.log ;/*[ 0, 0 ][ 1, 2 ][ 2, 5 ][ 3, 8 ][ 4, 11 ][ 5, 14 ][ 6, 17 ][ 7, 20 ][ 8, 23 ][ 9, 26 ][ 10, 29 ]*/ /*a : 0 |0-----------1-----------2-----------3-----------4----...b : 0 |0---1---2---3---4---5---6---7---8---9---10--11--12--...c : [0,0] |----------[1,2]-------[2,5]-------[3,8]-------[4,11]--...*/
- withTimestamp
;;b.listen true, console.log ; /*[ 0, 1544903873595 ][ 1, 1544903873896 ][ 2, 1544903874195 ][ 3, 1544903874497 ][ 4, 1544903874797 ]*/
- valueIs, valueIsNot
;;combinea, b.listen true, console.log /*[ 0, false ][ 1, false ][ 2, false ][ 3, true ][ 4, false ][ 5, false ]...*/
;;combinea, b.listen true, console.log /*[ 0, true ][ 1, true ][ 2, true ][ 3, false ][ 4, true ][ 5, true ]...*/
- switchMap
;;b.listen true, console.log ; /*0000111122*/ /*interval : 0 |0---------1---------2---------... (mapped-1) : 0 |0--0--0--0--0--0--0--0--0--0--...(mapped-2) : 0 |1--1--1--1--1--1--1-...(mapped-3) : 0 |2--2--2--2...... --- switchMap & mapTo --- [0,0] |0--0--0--01--1--1--12--2--2--2...*/
- flatMap
;;b.listen true, console.log ; /*00001010101201201201*/ /*interval : 0 |0---------1---------2---------... (mapped-1) : 0 |0--0--0--0--0--0--0--0--0--0--...(mapped-2) : 0 |1--1--1--1--1--1--1-...(mapped-3) : 0 |2--2--2--2...... --- flatMap & mapTo --- [0,0] |0--0--0--01-01-01-012012012012012012012012012*/
- every, some
;;;counter.listen true, console.log ;everya, b.listen true, console.log ; /*0true1false2false3false4false5false6true7false counter : 0 |0---1---2---3---4---5---6---7---...a : T |T---F---T---F---T---F---T---F---...b : T |T---F---F---T---F---F---T---F---...every : T |T---F---F---F---F---F---T---F---...
;;;counter.listen true, console.log ;somea, b.listen true, console.log ; /*0true1false2true3true4true5false6true7false... counter : 0 |0---1---2---3---4---5---6---7---...a : T |T---F---T---F---T---F---T---F---...b : T |T---F---F---T---F---F---T---F---...some : T |T---F---T---T---T---F---T---F---...
- toPromise
;;a.listen true, console.log ;pr.then console.log'resolve', v ; /*01234resolve 4*/
- toObservable
;;a.listen true, console.log'listen', v ;ob.subscribe console.log'subscribe', v ; /*listen 0subscribe 0subscribe 1listen 1subscribe 2listen 2subscribe 3listen 3subscribe 4listen 4*/
- once
;a.listen true, console.log ;setTimeouta.once.then console.log'once', v , 2500 ; /*0123once 34 interval : 0 |0-----1-----2-----3-----4----- ^ ^ | | | +---once resolves +---once is called*/
ToDo
- GUI application for generating RN code from data-flow graph
- add operators