简体   繁体   中英

Combine multiple observables from rxjs into a single buffer

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM