I'm trying to implement a super simple cache in RXJS. The way I want it to work is:
I tried the following code but it doesn't seem to return until after the call to the service responds. SwitchMap didn't do what I wanted either.
const partnerKey = `partner-${partnerId}`;
const localPartner = JSON.parse(localStorage.getItem(partnerKey));
this.partner$ = of(localPartner)
.pipe(concatMap(_ => partnersService.getById(partnerId)
.pipe(tap(partner => {
localStorage.setItem(partnerKey, JSON.stringify(partner));
return partner;
}))));
this.partner$.subscribe(x=> console.log(x));
console.log
should be called twice in the example above. I would have thought the concatMap would have multiple emits but maybe I'm understanding it wrong. Thanks for the help!
@kyler-johnson got me on the right track. I mistakenly though that eveything should be pipeable but that's not actually the case. I needed to use an operator outside of a pipe. In this case, I ended up splitting the two data fetches into their own observables and then concatting them.
const partnerKey = `partner-${partnerId}`;
const fetchDataFromLocalStorage$ = of(JSON.parse(localStorage.getItem('partner-' + partnerId)));
const fetchDataFromServer$ = partnersService.getById(partnerId)
.pipe(tap(partner => localStorage.setItem('partner-' + partnerId, JSON.stringify(partner))));
this.partner$ = concat(fetchDataFromLocalStorage$, fetchDataFromServer$);
You could use expand
which emits values directly and gets called recursively with the previous output as input. Return EMPTY
after the first execution to end the recursion.
const { of, EMPTY } = rxjs; const { delay, expand } = rxjs.operators; const fetchLocal = of('from local').pipe(delay(500)) const fetchRemote = of('from remote').pipe(delay(3000)) const source = fetchLocal.pipe( expand((value, index) => index < 1 ? fetchRemote : EMPTY) ); source.subscribe(console.log);
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
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.