Be carefull with this code:
const obs = Rx.Observable
.from(["a", "b", "c"])
.concatMap(value => Rx.Observable.of(value))
.scan((acc, value) => {
acc.push(value);
return acc;
}, []);
obs.subscribe(value => console.log(JSON.stringify(value)));
obs.subscribe(value => console.log(JSON.stringify(value)));
Result will be a bit unexpected:
["a"]
["a","b"]
["a","b","c"]
["a","b","c","a"]
["a","b","c","a","b"]
["a","b","c","a","b","c"]
"acc" variable is reference object and each subscriber gets stream data and adds data to the same object again.
It might be a lot of solutions for avoiding it, this is creation new object when stream data is received again :
var obs = Rx.Observable
.from(["a", "b", "c"])
.concatMap(value => Rx.Observable.of(value))
.scan((acc, value) => {
//clone initial value
if (acc.length == 0) {
acc = [];
}
acc.push(value);
return acc
}, []); // Note that an empty array is use as the seed
obs.subscribe(value => console.log(JSON.stringify(value)));
obs.subscribe(value => console.log(JSON.stringify(value)));
result as expected:
["a"]
["a","b"]
["a","b","c"]
["a"]
["a","b"]
["a","b","c"]
I hope it saves a lot time for someone
project
function passed toconcatMap
is supposed to return an observable, a promise or an array - not a string. – SabelleconcatMap
will iterate it and emit its individual characters. – Sabelle