Skip to content

Instantly share code, notes, and snippets.

@hahn-kev
Last active May 28, 2019 10:32
Show Gist options
  • Save hahn-kev/109d44fd7ed611e13d244b7b8254a5a6 to your computer and use it in GitHub Desktop.
Save hahn-kev/109d44fd7ed611e13d244b7b8254a5a6 to your computer and use it in GitHub Desktop.
RxJS cacheMap
function cacheMap<T, Result>(
cache$: Observable<{[key:string]: Observable<Result>}>,
selector: (value:T) => string,
projector: (key:string) => Observable<Result>) {
return function cmFunc(observable) {
return observable.pipe(
withLatestFrom(cache$),
switchMap(([value, cache]) => {
var key = selector(value);
if (cache[key]) return cache[key];
observable = projector(key).pipe(shareReplay());
cache[key] = observable;
return observable;
})
);
};
}
//use at https://rxviz.com/examples/custom
//there's some extra debug code in to see if the value came from the cache or not
const { interval, of, combineLatest, timer } = Rx;
const { map, switchMap, delay, shareReplay, share, groupBy, withLatestFrom } = RxOperators;
function cacheMap(cache$, selector, projector) {
return function cmFunc(observable) {
return observable.pipe(
withLatestFrom(cache$),
switchMap(([value, cache]) => {
var key = selector(value);
if (cache[key]) return cache[key].pipe(map(x => 'c' + x));
observable = projector(key).pipe(shareReplay());
cache[key] = observable;
return observable.pipe(map(x => 'p' + x));
})
);
};
}
var cache$ = timer(0, 6500).pipe(map(() => ({})));
function fetch(key) {
return of(key * 10);
}
timer(0, 1000).pipe(
map(x => x % 3),
cacheMap(cache$, x=>x, (key) => fetch(key)),
groupBy(x => x.includes('c'))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment