Rxjs: Operator to support AJAX persistence and multicasting

Created on 6 Oct 2016  路  12Comments  路  Source: ReactiveX/rxjs

Currently, there's a PR to remove cache #2012. The original intention of cache was to support use-cases, mostly coming from the Angular 2 community, revolving around wanting to persist successful AJAX requests, but still enable retry and retryWhen on failed AJAX requests.

This operator should

  1. Multicast the source observable
  2. Keep all values and "replay" them after a successful completion
  3. Enable "retrying" on error

    Stuff to consider, and unanswered questions:

  4. What are the behaviors when applied to a never-ending observable (Observable.interval(100), for example)

  5. How will this operator behave when applied to another hot observable?

    Possible Solutions

  • Re-add the cache operator but rename it to something more descriptive of it's purpose.
  • Add a simplified operator that takes no arguments called shareResults proposed here

For sake of discussion, we'll call this operator persist.

discussion

Most helpful comment

+1 for shareResults or even shareResult - we currently don't have usecases where we would want to replay more than the most recent result/value.

All 12 comments

I love the cache operator. The name doesn't matter to me, but I hope it exists somewhere. I'm aware that I can manually do this with publishReplay and connect, but cache was simpler and cleaner.

I often use it to share data across components/routes when making HTTP requests that don't need to be refreshed often:

https://github.com/sjtrimble/fluin.io/blob/master/src/app/shared/post.service.ts

Or I used it to eliminate re-processing of incoming data from data streams.

https://github.com/StephenFluin/ames/blob/e5502d1d0aadb44d44ec1fde659ed94ebf74057f/src/app/shared/auth.service.ts#L33

@StephenFluin it should be noted that publishReplay()/connect() can't be "retried", really. On failure, it's just done.

What if we simplified it to always persist all values and multicast and we called it shareResults? I think that implies that even after all value have arrived, all of them are kept as "results" and shared amongst all subscribers. There would be no arguments.

Observable.ajax.getJSON('http://something.com/whatever').shareResults();

Thoughts?

I also think shareResults keeps some similarity to the share operator, which has a similar behavior, retry-wise, but adds that little extra to imply result persistence.

Use-case to consider (shared auto-updating value, which should not be updated in periods without subscribers):

if (cache) { return cache; }

let serviceCall = Observable.ajax.getJSON('http://something.com/whatever')
    .retryWhen(errors => errors.concatMap(() => Observable.timer(period)));

cache = serviceCall
    .expand(() => Observable.timer(period).concatMap(() => serviceCall))
    .cache(1, period);

return cache;

@newsash I think we'll introduce a cache with more robust cache insertion and eviction logic for scenarios like that. It's probably out of scope for this common use case.

@blesh shareResults sounds great, any chance it will land in RC2? I'm trying to avoid building my own.

+1 for shareResults or even shareResult - we currently don't have usecases where we would want to replay more than the most recent result/value.

Any update on when this might land? It's a highly desirable operator.

Would it be possible to include a parameter that will control how many previous emissions are replayed?

That would also satisfy @IgorMinar request.

This is shareReplay, really. Closing.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matthewwithanm picture matthewwithanm  路  4Comments

samherrmann picture samherrmann  路  3Comments

OliverJAsh picture OliverJAsh  路  3Comments

giovannicandido picture giovannicandido  路  4Comments

cartant picture cartant  路  3Comments