I want to make sure that Observable.subscribe()
doesn't get executed if a different Observable yields true
.
An example use case would be making sure that user can trigger a download only if the previous one has finished (or failed) and there's only one download request executed at a time.
In order to control the execution flow, I had to rely on a state variable which seems a bit odd to me - is this a good pattern? In a v. likely case that it isn't - what would be a better approach?
I ended up with two subscriptions: Actions.sync
(using a Subject, public API, initialises a sync request) and isActive
(resolves to true
or `false, the name should be pretty self-explanatory.
let canDownload = true; // this one feels really, really naughty
const startedSyncRequests = new Rx.Subject();
const isActiveSync = startedSyncRequests.map(true)
.merge(completeSyncRequests.map(false))
.merge(failedSyncRequests.map(false))
.startWith(false)
.subscribe(isActive => canDownload = !isActive)
syncResources = ()=>{
startedSyncRequests.onNext();
// Mocked async job
setTimeout(()=> {
completeSyncRequests.onNext();
}, 1000);
};
Actions.sync
.filter( ()=> canDownload ) // so does this
.subscribe( syncResources );
You want
exclusive()
.The above will generate an observable every time the user makes a request. However,
exclusive
will drop any observables that come in before the previous one has completed, and then flattens the resulting messages into a single observable.Working example (using
interval
anddelay
):Reference: here