Feature Request
Brief
I want Subscriptions to support an async unsubscribe method, i.e. one that returns a Promise, and I want some operators behave differently to accomodate this.
The problem
I have a cold observable base that creates a new resource on subscription and disposes of it on unsubscribe.
let base = Observable.create(async sub => {
let res = Resource.create();
res.start().then(x => {
sub.next(x);
}, err => {
sub.error(err);
});
return {
async unsubscribe() {
await res.dispose();
}
}
});
The thing is that res.dispose() is async because it sends a request to a server, which is required to properly dispose of the resource.
Then, I use the base observable to create a dependent observable:
let derived = base.flatMap(res => {
let dres = DerivedResource.create(res);
return Observable.fromPromise(dres.start()).finalize(async () => {
await dres.dispose();
});
})
In rxjs, if I close the subscription to derived, first dres.dispose() will be called and only then will base.dispose() will be called.
Although I have not seen this in the documentation, it is the intuitive behavior and it does behave like this in practice.
However, in this case, the disposal is asynchronous. Rxjs doesn't support async disposal, so the two calls can effectively happen in parallel, and base might be disposed before derived, which is invalid behavior (derived is still using base at this time, after all)
Describe the solution you'd like
I want rxjs to allow for async disposal in order to make sure this kind of disposal works properly. This means awaiting on some unsubscribe calls before launching some new ones, depending on the operator.
An operator such as flatMap can first dispose of the subscriptions to the inner observables simultaneously using Promise.all, and only then dispose of the source sequence.
I can provide more detailed behavior changes if this suggestion gains any support/feedback.
The unsubscribe function will return void | Promise<void>, which will also allow the caller to determine when the subscription has been truly disposed.
Describe alternatives you've considered
I can't think of any other good solutions to the problem. If you can, please share them.
Other situations where this is helpful
-
It will be possible to signal to the caller that an async failure happened while unsubscribing. Right now, it's hard to say what should be done with a promise rejection in the unsubscribe method.
-
As a corollary of (1), operators can use this knowledge to improve their behavior. For example, if disposing of a resource is async and takes time, a retry or similar operator should wait until disposal of the previous resource has finished before trying to create another one. This may be desirable if, for example, two resources of the same arguments cannot coexist.
Feature Request
Brief
I want Subscriptions to support an async
unsubscribemethod, i.e. one that returns aPromise, and I want some operators behave differently to accomodate this.The problem
I have a cold observable
basethat creates a new resource on subscription and disposes of it on unsubscribe.The thing is that
res.dispose()is async because it sends a request to a server, which is required to properly dispose of the resource.Then, I use the
baseobservable to create a dependent observable:In rxjs, if I close the subscription to
derived, firstdres.dispose()will be called and only then willbase.dispose()will be called.Although I have not seen this in the documentation, it is the intuitive behavior and it does behave like this in practice.
However, in this case, the disposal is asynchronous. Rxjs doesn't support async disposal, so the two calls can effectively happen in parallel, and
basemight be disposed beforederived, which is invalid behavior (derivedis still usingbaseat this time, after all)Describe the solution you'd like
I want
rxjsto allow for async disposal in order to make sure this kind of disposal works properly. This means awaiting on someunsubscribecalls before launching some new ones, depending on the operator.An operator such as
flatMapcan first dispose of the subscriptions to the inner observables simultaneously usingPromise.all, and only then dispose of the source sequence.I can provide more detailed behavior changes if this suggestion gains any support/feedback.
The
unsubscribefunction will returnvoid | Promise<void>, which will also allow the caller to determine when the subscription has been truly disposed.Describe alternatives you've considered
I can't think of any other good solutions to the problem. If you can, please share them.
Other situations where this is helpful
It will be possible to signal to the caller that an async failure happened while unsubscribing. Right now, it's hard to say what should be done with a promise rejection in the
unsubscribemethod.As a corollary of (1), operators can use this knowledge to improve their behavior. For example, if disposing of a resource is async and takes time, a
retryor similar operator should wait until disposal of the previous resource has finished before trying to create another one. This may be desirable if, for example, two resources of the same arguments cannot coexist.