While reading the discussion in whatwg/dom#1461, I started wondering whether the underlying abstraction behind AbortSignal could be separated from its event-based aspects.
Related discussion:
- whatwg/dom#1461 β "
AbortSignal.timeout()may not abort past the timeout"
Motivation
AbortSignal today is fundamentally event-loop driven. In practice, this means that cancellation is not observable while the current agent is executing long-running synchronous work.
However, many use cases seem to only require synchronous observation of cancellation:
while (!signal.aborted) {
performWork();
}
In such cases, what matters is not event delivery, but the ability to observe cancellation state (aborted, reason) and react to it (throwIfAborted()).
Observation
AbortSignal currently combines multiple concerns:
-
Cancellation state
abortedreason
-
Cancellation observation
throwIfAborted()
-
Notification mechanism
"abort"event viaEventTarget
The issue above suggests that (1) and (2) are sometimes needed without (3), especially when event-loop progress is not guaranteed.
Question
Would it make sense to think about an "AbortSignal-like" abstraction that includes:
abortedreasonthrowIfAborted()- (possibly) composition helpers like
any()
but does not require event dispatch?
In other words:
AbortSignal
= AbortSignal-like (state + logic)
+ EventTarget (notification)
Possible implications
If such an abstraction existed, different implementations could be possible:
- DOM
AbortSignal(event-driven) - Timeout-based signals (clock-driven)
- Shared-state signals (e.g. across agents, possibly via shared memory)
- Userland implementations
In particular, some environments may want cancellation state to be observable independently of the event loop, while still optionally supporting event-based notifications.
Scope
I am not proposing changes to AbortSignal itself.
Rather, I am wondering:
- Is this separation of concerns meaningful?
- Would an "AbortSignal-like" abstraction make sense at the language level?
- Or is this better left as platform-specific or userland patterns?
Curious to hear thoughts, especially if similar ideas have been explored before.
Related discussion about one possible implementation approach:
- tc39/proposal-structs#67 β shared cancellation state as a possible Shared Structs use case