Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
fix(SequentialEvent.Emit): Copy handlers array on event emission
Browse files Browse the repository at this point in the history
Avoids the error of `undefined` handler on race condition with `once` handlers
  • Loading branch information
Gerkin committed Aug 13, 2018
1 parent dc99ff8 commit fe7e727
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/sequential-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class SequentialEvent {
return Promise.resolve();
}

const retPromise = emitHandlers(handler, this, args);
const retPromise = emitHandlers(handler.slice(0), this, args);

return retPromise;
}
Expand Down
5 changes: 0 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ export const getNextPromise = (
return (resolve: Function, reject: (reason: any) => any) => {
const _getNextPromise = (prevResolve?: any) => {
// Handle if an event handler disapeared during event dispatching
const handlersLength2 = handlers.length;
if (handlersLength2 !== handlersLength) {
i -= handlersLength - handlersLength2;
handlersLength = handlersLength2;
}
if (i < handlersLength) {
const stepArgs =
'undefined' !== typeof prevResolve
Expand Down
14 changes: 14 additions & 0 deletions test/sequential-event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,20 @@ describe('Once & remove listeners', () => {

expect(test).toHaveBeenCalledTimes(1);
});
it('Paralllel execution of "once" should be prevented inside the handler function', async () => {
const tests = [jest.fn(), jest.fn()];
const mySequentialEvent = new SequentialEvent();

mySequentialEvent.once('a', tests);
await Promise.all([
mySequentialEvent.emit('a', 'FOO', 1),
mySequentialEvent.emit('a', 'BAR', 42),
]);
expect(tests[0]).toHaveBeenCalledTimes(1);
expect(tests[0]).toHaveBeenCalledWith('FOO', 1);
expect(tests[1]).toHaveBeenCalledTimes(1);
expect(tests[1]).toHaveBeenCalledWith('BAR', 42);
});
it('Remove all listeners', async () => {
const tests = [jest.fn(), jest.fn()];
const mySequentialEvent = new SequentialEvent();
Expand Down

0 comments on commit fe7e727

Please sign in to comment.