Closed domfarolino closed 8 months ago
Yeah. This API in RxJS is called closed
, and used fairly often, but active
is a MUCH better name for it, as most checks are like if (subscriber.active) { /* do things */ }
, and because it better describes what you're checking. You're checking to see if the subscriber is still "active" before you continue doing work.
Replaced with https://github.com/WICG/observable/pull/82 since this was merged by mistake.
This closes https://github.com/WICG/observable/issues/76. This PR introduces the
subscriber.active
boolean attribute that can be used from within an Observable to determine whether a subscription is still active. I am still personally a tiny but unsure whether this is really necessary, so I'd like to use this space to describe the semantics and how it differs from other APIs, so we can come to a conclusion on this, since @benlesh feels much more strongly about this API.On the surface it seems that
subscriber.active === !subscriber.signal.aborted
[^1], however this is not quite true. The lifecycle of an Observable is the following:subscriber.complete()/error()
is called from scriptObserver
dictionary for that matter.Observer#complete()/error()
body is runSubscriber#signal
is aborted (via an internalAbortController
)subscriber.signal.aborted
is truesubscriber.addTeardown()
) will run, as part of the abort algorithms associated withsubscriber.signal
The
subscriber.active
attribute intends to expose precisely when a subscription no longer becomes active (just before theObserver#complete()/error()
body is run), which is before thesubscriber.signal
is finally aborted. The only observable consequence I can think of for this is inside thecomplete()
/error()
methods, wheresubscriber.active
is already false butsubscriber.signal.aborted
is not yet true (since teardowns haven't run yet).I think that
subscriber.active
is a more sensible and ergonomic way to express the concept of an "inactive subscription", however I only hesitate to add it because I don't love the idea of having two different ways of getting this information with slightly different semantics. I'm curious if anyone would rely onsubscriber.active
in a way that!subscriber.signal.aborted
couldn't be used for (thus causing broken code).Here's an I can think of where
subscriber.signal.aborted
is insufficient for stopping an infinite loop:How important is it to protect against this kind of (highly contrived!) scenario? Or are there way less contrived scenarios where
subscriber.signal.aborted
is a footgun, and wheresubscriber.active
would be critical.[^1]: Remember of course that
subscriber.signal
is aborted absolutely whenever a subscription is ended, not just when the subscriber unsubscribes / aborts thesignal
that it passed intosubscribe()
.