AbortController.signal.addEventListener does not handle capture option #51703
Copy link
Copy link
Closed
Labels
staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
Description
Version
v20.11.0
Platform
Linux petrov-dm 6.5.0-15-generic #15~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 12 18:54:30 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
No response
What steps will reproduce the bug?
Run code:
const controller = new AbortController();
controller.signal.addEventListener('abort', () => {
console.log('foo');
});
controller.signal.addEventListener(
'abort',
() => {
console.log('bar');
},
{ capture: true },
);
controller.abort();How often does it reproduce? Is there a required condition?
No response
What is the expected behavior? Why is that the expected behavior?
expected output (like in firefox):
bar
foo
What do you see instead?
actual output:
foo
bar
Additional information
In Firefox there is properly behavior but i dont know how this described in specifications
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
Activity
climba03003 commentedon Feb 8, 2024
In chrome, it follows the order of registered event listener.
krutoo commentedon Feb 8, 2024
@climba03003 yes but I thought that
capture: trueoption should affect listener call order in the same way as in the DOM eventsaduh95 commentedon Feb 8, 2024
In Safari, like Firefox, the output is:
It'd be interesting to pin down what the spec says about this.
/cc @nodejs/web-standards
KhafraDev commentedon Feb 9, 2024
Node doesn't implement bubbling, because there's no tree-like structure that's hierarchical (think about an HTMLElement that can have children/a parent). Even if there was, AbortController/EventTarget has no hierarchy, and should ignore
captureregardless.Furthermore, here are the steps to invoke a callback (a callback is the user-supplied function when using addEventListener):
Note that an eventPhase, in node, can only be
AT_TARGETorNONEThere are a few important things to note here.
I'm not an expert at EventTarget, but it would appear as though node is correct, given the differences between browsers and servers. Maybe someone else can chime in who knows more.
github-actions commentedon May 23, 2026
This issue has been marked as stale due to 210 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
krutoo commentedon May 23, 2026
I agree that there's no hierarchy in Node, but it seemed logical to me that if I add two listeners to a controller, one of which has capture:true, then regardless of the registration order, the one with capture:true will be called first.
However, overall, this isn't a problem for me, thanks for the clarification.