I'm studying RXJS and stuck with the problem: the same code with operators "reduce" and "scan" works in different ways, but I think that must return equal result. Example below. Please help.
const txtElement1 = document.getElementById('txt1');
const txtElement2 = document.getElementById('txt2');
const txtElement3 = document.getElementById('txt3');
// function return Observable
function get(array, initValue) {
return Rx.Observable.create(observer => {
let timer = initValue;
array.forEach(item => {
setTimeout(() => observer.next(item), timer);
timer += 1000;
});
});
}
// 1) don't work with "reduce"
var stream1$ = get(['John', 'Ann', 'Bob'])
.reduce(function(acc, x) {
return acc + ` ${x}`;
}, 'first - ');
stream1$.subscribe(text => txtElement1.innerHTML = text);
// 2) the same code, but with "scan" - working
var stream2$ = get(['John', 'Ann', 'Bob'])
.scan(function(acc, x) {
return acc + ` ${x}`;
}, 'second - ');
stream2$.subscribe(text => txtElement2.innerHTML = text);
// 3) and the simple Observable with "reduce" - working
var stream3$ = Rx.Observable.from(['John', 'Ann', 'Bob'])
.reduce(function(acc, x) {
return acc + ` ${x}`;
}, 'third - ');
stream3$.subscribe(text => txtElement3.innerHTML = text);
there almost the same but scan emits each iteration. and reduce just emits a final results. i like scan when i want to actually see what reduce is doing. so sometimesi . use reduce and i cant visualize what reduce is actually doing. in this case i simple swap out reduce for scan since it will emit on each iteration. this way i can put in a log statement and see the results for each iteration.
From RxJS documentation,
Example codes
Scan
For each value emitted by the Observable, scan emits corresponding output sequentially, So the Output will have 3 values for range 1 to 3, as follows
Reduce
Reduce function reduces the values from observables to a single value (final result) and emit. So the output will be as follows,
Rx.scan is continuous whereas reduce is not continuous.