question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

flatMapLatest – add next observable before removing previous

See original GitHub issue

In AbstractPool there is an option drop that is used by flatMapLatest(), when drop is set to old then the old source is unplugged from the pool before the next source is added:

      /* snip */
      } else if (this._drop === 'old') {
        this._removeOldest();
        this._add(obj, toObs);
      }
      /* snip */

https://github.com/rpominov/kefir/blob/master/src/many-sources/abstract-pool.js#L37

Is there a strong opinion against either a) adding another option, perhaps overlapping, to softly drop the old stream (add the next stream before removing the eldest) or b) making the default behavior for old add the next stream before removing the old stream.

Option (b) seems perhaps a little risky and a breaking change. But having control over this would be beneficial in some cases where you are switching between streams, but don’t want them to deactivate it unless they are unused in the next streams activation chain.

Example:

const channelA = Kefir.stream((emitter) => {
  console.log('connect a');
  let count = 0, id = setInterval(() => emitter.value(count++), 250);
  return () => { console.log('disconnect a'); clearInterval(id); };
});

const channelB = Kefir.stream((emitter) => {
  console.log('connect b');
  let count = 0, id = setInterval(() => emitter.value(count++), 250);  
  return () => { console.log('disconnect b'); clearInterval(id); };
});

const data = {
  a: channelA,
  b: Kefir.combine([channelA, channelB]),
  c: channelB,
};

Kefir.sequentially(1000, ['a', 'b', 'c', undefined])
  .flatMapLatest(p => p ? data[p] : Kefir.never())
  .log('result');

Console:

> connect a
> result <value> 0
> result <value> 1
> result <value> 2
> disconnect a
> connect a
> connect b
> result <value> [0, 0]
> result <value> [1, 0]
> result <value> [1, 1]
> result <value> [2, 1]
> result <value> [2, 2]
> disconnect a
> disconnect b
> connect b
> result <value> 0
> result <value> 1
> result <value> 2
> disconnect b
> result <end>

Notice how both a and b disconnect and immediately reconnect on the swap. What, I think, I would like in some situations:

> connect a
> result <value> 0
> result <value> 1
> result <value> 2
> connect b
> result <value> [3, 0]
> result <value> [3, 1]
> result <value> [4, 1]
> result <value> [4, 2]
> disconnect a
> result <value> 3
> result <value> 4
> result <value> 5
> disconnect b
> result <end>

Is there a different way to achieve this behavior without having to alter the behavior of AbstractPool. In my real use case, these Kefir.stream() observables wrap over a socket.io connection, so it’s less-than-ideal to tear down the connection between sibling projections, but at the same time, its less-than-ideal to keep the socket going for unused/unneeded projections.

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
32bitkidcommented, Feb 16, 2017

That’s what I was thinking as well. I’ll make a pull request soon with a potential implementation. Thanks!

On Feb 15, 2017, at 11:43 PM, Roman Pominov notifications@github.com wrote:

Yeah, that makes sense. Although I’m also worry that option (b) can be to dangerous, it can introduce subtle hard to track changes in behavior in many people programs.

Seems like nothing stops us from doing option (a) though. We can then also add an argument to flatMapLatest so it would support following signatures:

// supports now () (fn: Function)

// new (fn: Function, overlapping: bool) (overlapping: bool) — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

0reactions
bpintocommented, Aug 20, 2021

I’ve implemented this on https://github.com/kefirjs/kefir/pull/320, please have a look when you have a chance. The console output is slightly different but that’s correct IMO as the intervals inside each stream are different.

Read more comments on GitHub >

github_iconTop Results From Across the Web

FlatMapLatest with Replay - rx swift - Stack Overflow
This is an issue, because flatMapLatest does not provide for an ability for a replay on old values of existing observables. See below...
Read more >
Transforming Operators in RxSwift: map, flatMap & flatMapLatest
The next operator is useful if you only want to receive updates from the most recent observable and unsubscribe from old ones. 3....
Read more >
Observable | baconjs
Observable is the base class for EventsStream and Property ... Adds an extra Next event just before End. The value is created by...
Read more >
RxSwift flatMapLatest without disposing previous observables ...
asObservable() .debug("before") .flatMap ({ (value) -> Observable<String> in let task: Observable<String> = Observable.create { observer in ...
Read more >
RxSwift Transforming Operators: map, flatMap, flatMapLatest ...
In general, When you have an item emitted from observable and you want ... and flatMapLatest is it disposes previous subscription when new ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found