3

Suppose I have an async method that runs a query and returns a set of results:

Task<IEnumerable<Foo>> FetchResultSet();

And I have an observable that fires whenever the result set needs to be fetched again:

IObservable<Unit> NeedToRefetch;

What I want is:

IObservable<IEnumerable<Foo>>

Which would (1) run the query and yield an initial result set, and (2) each time NeedToRefetch fires, run the query again and yield another result set.

What's the best way to compose this observable?

If I didn't need that initial result set, I could do this:

NeedToRefetch
    .Select(_ => Observable.FromAsync(() => FetchResultSet()))
    .Concat();

So to make sure that the query gets run at least once, I could do this:

Observable.Return(Unit.Default)
    .Merge(NeedToRefetch)
    .Select(_ => Observable.FromAsync(() => FetchResultSet()))
    .Concat();

But then I started reading about cold and hot observables and I wondered if instead I should do something like this:

var initial = Observable.FromAsync(() => FetchResultSet());
var later = NeedToRefetch
    .Select(_ => Observable.FromAsync(() => FetchResultSet()))
    .Concat();
initial
    .Merge(later);

And then I wondered if this is a case where I am supposed to use Observable.Create.

And I then I stopped wondering and wrote this question.

Askolein
  • 3,250
  • 3
  • 28
  • 40
Eric Sink
  • 342
  • 1
  • 7
  • 1
    Hi Eric, can you rephrase your question to be a bit more objective? Right now, "what's the best way" is an opinion-based question... we don't even know what metric you're measuring "best" by, and primarily opinion-based questions are off-topic here. What problem with your code, specifically and objectively, would using cold/hot observables solve? Will your code run fine without them? Those are a couple things to consider when constructing a question that might help you solve it yourself. – TylerH Dec 17 '16 at 16:51
  • I assume you are a bot? If I just remove the word "best" do I avoid the trigger words? – Eric Sink Dec 17 '16 at 17:23
  • No, and please don't be rude. What's the best way to do anything? What do you mean best? Fastest? Fewest LOC? Most secure? Easiest to read by another human? Smallest file size? Why is whichever metric you choose the "best" one? In case you can't tell, I'm trying to help you improve your question so that you're more likely to get a (better) answer. – TylerH Dec 17 '16 at 23:16
  • @Erik what's about second option but without .Concat? – Igor Lizunov Dec 18 '16 at 06:17

1 Answers1

1

I'd say you're almost there. You can use your original approach. To make it run once immediately you can include a StartWith():

NeedToRefetch
    .StartWith(Unit.Default)
    .Select(_ => Observable.FromAsync(() => FetchResultSet()))
    .Concat();
Jon G Stødle
  • 3,844
  • 1
  • 16
  • 22