4
votes

How do I get multiple subscribers waiting the same promise to resolve if it is already inflight with latecomers given a new resolution?

doSomething = () => {
  return new Promise((resolve) => {
     setTimeout(() => resolve(Math.random(), 1000)
  })
}

// how to define obs?

obs.subscribe(v => console.log(v)); // 0.39458743297857473
obs.subscribe(v => console.log(v)); // 0.39458743297857473
obs.subscribe(v => console.log(v)); // 0.39458743297857473

setTimeout(() => obs.subscribe(v => console.log(v)), 2000); // 0.9485769395265746

I'd like the observable to remain cold until the first subscriber, then go cold again after the result is streamed to all subsequent concurrent subscribers. I basically don't want any concurrent requests to the same underlying function.

1

1 Answers

3
votes

You can use defer as the creation-operator and then share the stream:

doSomething = () => {
  return new Promise((resolve) => {
     setTimeout(() => resolve(Math.random(), 1000));
  });
}

const obs = Rx.Observable
    .defer(doSomething)
    .share();

obs.subscribe(console.log); // resolve #1
obs.subscribe(console.log); // resolve #1
obs.subscribe(console.log); // resolve #1

setTimeout(() => obs.subscribe(console.log), 2000); // resolve #2
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>