'Sharing combine Observables in rxjs without recalculating mapped values

Not quite sure how to formulate this question, but I'm trying to combine one event with multiple other events, in a way in which the shared event's pipeline is only calculated once (to avoid unnecessary calculations or sever requests)

Here is an example of the problem I want to solve:

import {
  fromEvent,
  combineLatest,
  map
} from 'rxjs';
import Emitter from 'events'

const emitter = new Emitter()

const shared = fromEvent(emitter, 'shared')
const specific1 = fromEvent(emitter, '1')
const specific2 = fromEvent(emitter, '2')

const pipe = shared.pipe(
  map(() => {
    const calculatedValue = Math.random()
    // This function is called twice, instead of once
    console.log(`calculation performed: ${calculatedValue}`)
    return calculatedValue
  })
)

/**
 * @param {import('rxjs').Observable<any>} observable 
 */
const combine = (observable) => {
  combineLatest([pipe, observable]).subscribe(console.log)
}

combine(specific1)
combine(specific2)

console.log('Emitting shared event')
emitter.emit('shared')
// logs: "calculation performed: [random value]
// logs: "calculation performed: [a different random value]

console.log('Emitting event 1')
emitter.emit('1')
// uses the first random number

console.log('Emitting event 2')
emitter.emit('2')
// uses the second random number

The first and second combined observables are now using two different values, although I want them to be using the same. Is there a way I can ensure the map function is only called once, while still using rxjs functions (i.e. avoiding writing a variable with the calculated value)

Another example you can see here, using html buttons



Solution 1:[1]

You can use shareReplay

const pipe = sharedEvent.pipe(
  map(() => {
    const val = randomNumber()
    addToFeed(`Shared event executed, calculated value ${val}`)
    return val
  }),
  shareReplay()
)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Saptarsi