Search code examples
ecmascript-6rxjsreactive-extensions-js

Rx: Run code after all subscriptions have completed for one 'next'


Say I have a subject somewhere in my code

mySubject$ = new Subject()

Elsewhere in the code, any number of subscriptions are made, e.g.

someSubscription = mySubject$.subscribe(() => console.log('I love streams'))
anotherSubscription =  mySubject$.subscribe(() => console.log('me too!'))

When I .next()the subject, both subscription fire as expected.

How can I hook into the rx mechanism so that I can run some code after all subscriptions have finished running their code (for that single next event)?

Is there something like mySubject$.onAllSubscriptionsCompleted(() => console.log('all done')

Or what are alternatives to achieving this?


Solution

  • RxJS doesn't have such backward (upward?) event propagation, unless its a subscription/unsubscription.

    Strictly saying: its not an Rx-way to have that relation between subscriber and an observable.

    Yet, there are ways to achieve that:

    • you could have another Subject(s) to push "handled" notifications to, and handle from your observable. A nightmarish thing to support, imho

    • have your subscribers to resubscribe and react in your observable to that. A speculation on that subscription/unsubscription event propagation. Seems even more nightmarish. And it should

    • have some kind of back pressure, simplest of which is a concatMap, inside of which you could perform all your handling. Yet with this approach you'll have to rethink those generator-handlers relations

    Heres a rough illustration of a flow using concatMap

                                    handler1
    source$ -> concatMap( forkJoin( handler2 ) ) -> subscribe( here all handlers finished )
                                    handler3
    

    If you want to learn more on back pressure, heres an article on backpressure techniques in RxJS