I have 2 websocket connections (using LiveQuery
from Parse
if that makes a difference).
For each websocket I have 3 events that I want to capture, "create"
, "update"
, and "delete"
.
A bunch of updates are likely to come at once, so for a single event I use a buffer to capture a sequence of updates that come through at once:
const base = fromEvent(listener, type);
const triggerBuffer = base.pipe(debounceTime(500));
const buffered = base.pipe(buffer(triggerBuffer));
That works fine. When a bunch of updates come from the server they get buffered and are all emitted at once.
What I want is to combine all of the events from both websockets into a single update. I've tried to achieve this with the zip
operator like so:
const setupServerObservable = (listener, listenerName) => type => {
const base = fromEvent(listener, type);
return base.pipe(map(x => ({ [listenerName]: { [type]: x } })));
};
const setupServerObservables = subscriptions => {
const joins = setupServerObservable(subscriptions.joins, "joins");
const containers = setupServerObservable(
subscriptions.containers,
"containers"
);
const eventTypes = ["update", "create", "delete"];
const allJoins = eventTypes.map(joins);
const allContainers = eventTypes.map(containers);
const all = allJoins.concat(allContainers);
const zippedObservables = zip(all);
console.log(zippedObservables);
const triggerBuffer = zippedObservables.pipe(debounceTime(500));
const buffered = zippedObservables.pipe(buffer(triggerBuffer));
return buffered;
};
But when I try to subscribe to this newly created Observable
it doesn't emit any updates from the server. That console.log(zippedObservables)
produces the following output:
Observable {_isScalar: false, source: Observable, operator: ZipOperator}
operator: ZipOperator
resultSelector: Array(6)
0: Observable {_isScalar: false, source: Observable, operator: MapOperator}
1: Observable {_isScalar: false, source: Observable, operator: MapOperator}
2: Observable {_isScalar: false, source: Observable, operator: MapOperator}
3: Observable {_isScalar: false, source: Observable, operator: MapOperator}
4: Observable {_isScalar: false, source: Observable, operator: MapOperator}
5: Observable {_isScalar: false, source: Observable, operator: MapOperator}
length: 6
__proto__: Array(0)
__proto__: Object
source: Observable {_isScalar: false, _subscribe: ƒ}
_isScalar: false
__proto__: Object
I think I'm probably misunderstanding what the zip
operator does but I wasn't able to make it work with merge
or concat
either.
Once I looked at the tutorial posted in the comments I realised that zip
was not what I wanted.
I tried the same thing with merge
but it didn't work. It seems that merge
does not accept an array, it has to accept each Observable
to merge as a separate parameter like so:
const merged = merge(all[0], all[1], all[2], all[3], all[4], all[5]);
So the final code is:
const setupServerObservable = (listener, listenerName) => type => {
const base = fromEvent(listener, type);
return base.pipe(map(x => ({ [listenerName]: { [type]: x } })));
};
const setupServerObservables = subscriptions => {
const joins = setupServerObservable(subscriptions.joins, "joins");
const containers = setupServerObservable(
subscriptions.containers,
"containers"
);
const eventTypes = ["update", "create", "delete"];
const allJoins = eventTypes.map(joins);
const allContainers = eventTypes.map(containers);
const all = allJoins.concat(allContainers);
const merged = merge(all[0], all[1], all[2], all[3], all[4], all[5]);
const triggerBuffer = merged.pipe(debounceTime(500));
const buffered = merged.pipe(buffer(triggerBuffer));
return buffered;
};
It would be nice if there was a way to do this with an array but it seems not.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.