Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ability to pass array of event names to EventEmitter.prototype.once #196

Merged
merged 1 commit into from
Oct 9, 2023

Conversation

lawrence-forooghian
Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian commented Sep 28, 2023

This copies across the change from ably/ably-js#1453 — see explanation there.

The removed code in the current PR also had a bug — the second argument in the removed code self.off(eventName, this) was incorrectly populated and this made the removed code equivalent to self.off(eventName); that is, it removed all listeners for the given event name. I believe that the removal of this code accounts for the increased expected number of calls to context.spy in one of the tests here. I’m not sure what reasoning led to the previous expected count of 3 (perhaps the expectation was written just based on the number of calls observed when running the code), but here’s my reasoning for the expectation of 4 calls:

Before context.eventEmitter['off']('myEvent', context.spy), the following calls are relevant to context.spy:

  • eventEmitter['on'](context.spy);
  • eventEmitter['on']('myEvent', context.spy);
  • eventEmitter['on'](['myEvent', 'myOtherEvent', 'myThirdEvent'], context.spy);
  • eventEmitter['once'](context.spy);
  • eventEmitter['once']('myEvent', context.spy);

After context.eventEmitter['off']('myEvent', context.spy), the following calls are relevant to context.spy:

  • eventEmitter['on'](context.spy);
  • eventEmitter['on'](['myEvent' /* no longer applies *\/, 'myOtherEvent', 'myThirdEvent'], context.spy);
  • eventEmitter['once'](context.spy);

After context.eventEmitter['emit']('myEvent', ''), the following calls are relevant to context.spy:

  • eventEmitter['on'](context.spy);
  • eventEmitter['on'](['myEvent' /* no longer applies */, 'myOtherEvent', 'myThirdEvent'], context.spy);

And hence calling context.eventEmitter['emit']('myOtherEvent', '') calls context.spy a further two times.

….once

This copies across the change from commit cd4f7b3 in ably-js:

> This functionality is implemented by wrapping the listener argument in
> another listener.  This means that the event emitter does not hold a
> reference to the listener argument (other than that held indirectly
> through the wrapper) and so it is not possible to remove this listener
> using `off(..., listener)`.
>
> The client library specification does not specify a version of `once`
> which accepts an array of event names, and we do not advertise it as
> part of the public API. So, I think the simplest thing is to remove this
> functionality.

The removed code in the current commit also had a bug — the second
argument in the removed code `self.off(eventName, this)` was incorrectly
populated and this made the removed code equivalent to
`self.off(eventName)`; that is, it removed _all_ listeners for the given
event name. I believe that the removal of this code accounts for the
increased expected number of calls to context.spy in one of the tests
here. I’m not sure what reasoning led to the previous expected count of
3 (perhaps the expectation was written just based on the number of calls
observed when running the code), but here’s my reasoning for the
expectation of 4 calls:

Before `context.eventEmitter['off']('myEvent', context.spy)`, the
following calls are relevant to context.spy:

- eventEmitter['on'](context.spy);
- eventEmitter['on']('myEvent', context.spy);
- eventEmitter['on'](['myEvent', 'myOtherEvent', 'myThirdEvent'], context.spy);
- eventEmitter['once'](context.spy);
- eventEmitter['once']('myEvent', context.spy);

After `context.eventEmitter['off']('myEvent', context.spy)`, the
following calls are relevant to context.spy:

- eventEmitter['on'](context.spy);
- eventEmitter['on'](['myEvent' /* no longer applies */, 'myOtherEvent', 'myThirdEvent'], context.spy);
- eventEmitter['once'](context.spy);

After `context.eventEmitter['emit']('myEvent', '')`, the following calls
are relevant to context.spy:

- eventEmitter['on'](context.spy);
- eventEmitter['on'](['myEvent' /* no longer applies *\/, 'myOtherEvent', 'myThirdEvent'], context.spy);

And hence calling `context.eventEmitter['emit']('myOtherEvent', '')`
calls context.spy a further two times.
@dpiatek dpiatek force-pushed the remove-EventEmitter-once-multiple-events branch from ab13900 to eee7507 Compare October 6, 2023 09:09
@lawrence-forooghian lawrence-forooghian merged commit bb12d11 into main Oct 9, 2023
5 checks passed
@lawrence-forooghian lawrence-forooghian deleted the remove-EventEmitter-once-multiple-events branch October 9, 2023 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants