Skip to content
Astera Technology

Use a once listener safely during reentrant dispatch

Dispatch the same event inside a once listener and count invocations.

Download complete case notes and answer keys ↓

Trace the fixed program

Use a local EventTarget with no DOM node. Its once listener immediately dispatches another sample event. Predict the count before the outer dispatch returns.

Complete original program
const target=new EventTarget();let count=0;
target.addEventListener('sample',()=>{count++;target.dispatchEvent(new Event('sample'));},{once:true});
target.dispatchEvent(new Event('sample'));
console.log(count);
Exact console output
1
Values and execution
Point in dispatchListener presentCount
Before outer callbackRemoved0
Inside outer callbackAbsent for nested dispatch1
Outer dispatch completeAbsent1

Explain the result

The once listener is removed before its callback is invoked. Nested synchronous dispatch sees it already removed. The guarantee is about this registered listener, not durable deduplication, all listeners, or a later registration.

Test the alternative

Removing at the callback’s end is too late for reentrant dispatch. This counterexample caps recursion at two callbacks; never remove the count guard while running it.

Separate finite alternative
const target=new EventTarget();let count=0;
function listener(){count++;if(count<2)target.dispatchEvent(new Event('sample'));target.removeEventListener('sample',listener);}
target.addEventListener('sample',listener);target.dispatchEvent(new Event('sample'));
console.log(count);
Alternative output
2

Work the boundary case

Would dispatching again afterward call the original once listener?

Show the worked answer

No. It remains removed. A newly registered once listener can run on a later dispatch.

Fresh boundary program
const target=new EventTarget();let count=0;const listener=()=>count++;
target.addEventListener('sample',listener,{once:true});target.dispatchEvent(new Event('sample'));target.dispatchEvent(new Event('sample'));
target.addEventListener('sample',listener,{once:true});target.dispatchEvent(new Event('sample'));
console.log(count);
Boundary output
2

Original example files