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

lib: refactor events.js #36528

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 27 additions & 19 deletions lib/events.js
Expand Up @@ -22,7 +22,12 @@
'use strict';

const {
ArrayPrototypeJoin,
ArrayPrototypePush,
ArrayPrototypeShift,
ArrayPrototypeSlice,
ArrayPrototypeSplice,
ArrayPrototypeUnshift,
Boolean,
Error,
ErrorCaptureStackTrace,
Expand All @@ -39,6 +44,7 @@ const {
ReflectApply,
ReflectOwnKeys,
String,
StringPrototypeSplit,
Symbol,
SymbolFor,
SymbolAsyncIterator
Expand Down Expand Up @@ -200,7 +206,7 @@ EventEmitter.init = function(opts) {
this._maxListeners = this._maxListeners || undefined;


if (opts && opts.captureRejections) {
if (opts?.captureRejections) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to benchmark these changes. The entire events.js file is one of the most performance sensitive in core and changes here can have massive impact throughout. Last I benchmarked, optional chaining still had some performance lag that hadn't been fully optimized out. That's not a block on this on it's own but let's be sure to run benchmarks before this lands.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not a fan of the optional chaining operator. I think it hinders readability.

if (typeof opts.captureRejections !== 'boolean') {
throw new ERR_INVALID_ARG_TYPE('options.captureRejections',
'boolean', opts.captureRejections);
Expand Down Expand Up @@ -310,16 +316,18 @@ function enhanceStackTrace(err, own) {
} catch {}
const sep = `\nEmitted 'error' event${ctorInfo} at:\n`;

const errStack = err.stack.split('\n').slice(1);
const ownStack = own.stack.split('\n').slice(1);
const errStack = ArrayPrototypeSlice(StringPrototypeSplit(err.stack, '\n'),
1);
const ownStack = ArrayPrototypeSlice(StringPrototypeSplit(own.stack, '\n'),
1);

const [ len, off ] = identicalSequenceRange(ownStack, errStack);
if (len > 0) {
ownStack.splice(off + 1, len - 2,
' [... lines matching original stack trace ...]');
ArrayPrototypeSplice(ownStack, off + 1, len - 2,
' [... lines matching original stack trace ...]');
}

return err.stack + sep + ownStack.join('\n');
return err.stack + sep + ArrayPrototypeJoin(ownStack, '\n');
}

EventEmitter.prototype.emit = function emit(type, ...args) {
Expand Down Expand Up @@ -437,9 +445,9 @@ function _addListener(target, type, listener, prepend) {
prepend ? [listener, existing] : [existing, listener];
// If we've already got an array, just append.
} else if (prepend) {
existing.unshift(listener);
ArrayPrototypeUnshift(existing, listener);
} else {
existing.push(listener);
ArrayPrototypePush(existing, listener);
}

// Check for listener leak
Expand Down Expand Up @@ -542,7 +550,7 @@ EventEmitter.prototype.removeListener =
return this;

if (position === 0)
list.shift();
ArrayPrototypeShift(list);
else {
if (spliceOne === undefined)
spliceOne = require('internal/util').spliceOne;
Expand Down Expand Up @@ -670,7 +678,7 @@ function arrayClone(arr) {
case 5: return [arr[0], arr[1], arr[2], arr[3], arr[4]];
case 6: return [arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]];
}
return arr.slice();
return ArrayPrototypeSlice(arr);
}

function unwrapListeners(arr) {
Expand Down Expand Up @@ -706,9 +714,9 @@ function getEventListeners(emitterOrTarget, type) {
}

async function once(emitter, name, options = {}) {
const signal = options ? options.signal : undefined;
const signal = options?.signal;
validateAbortSignal(signal, 'options.signal');
if (signal && signal.aborted)
if (signal?.aborted)
throw lazyDOMException('The operation was aborted', 'AbortError');
return new Promise((resolve, reject) => {
const errorListener = (err) => {
Expand Down Expand Up @@ -762,7 +770,7 @@ function eventTargetAgnosticRemoveListener(emitter, name, listener, flags) {

function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === 'function') {
if (flags && flags.once) {
if (flags?.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
Expand All @@ -779,7 +787,7 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
function on(emitter, event, options) {
const { signal } = { ...options };
validateAbortSignal(signal, 'options.signal');
if (signal && signal.aborted) {
if (signal?.aborted) {
throw lazyDOMException('The operation was aborted', 'AbortError');
}

Expand All @@ -791,7 +799,7 @@ function on(emitter, event, options) {
const iterator = ObjectSetPrototypeOf({
next() {
// First, we consume all unread events
const value = unconsumedEvents.shift();
const value = ArrayPrototypeShift(unconsumedEvents);
if (value) {
return PromiseResolve(createIterResult(value, false));
}
Expand All @@ -813,7 +821,7 @@ function on(emitter, event, options) {

// Wait until an event happens
return new Promise(function(resolve, reject) {
unconsumedPromises.push({ resolve, reject });
ArrayPrototypePush(unconsumedPromises, ({ resolve, reject }));
});
},

Expand Down Expand Up @@ -873,18 +881,18 @@ function on(emitter, event, options) {
}

function eventHandler(...args) {
const promise = unconsumedPromises.shift();
const promise = ArrayPrototypeShift(unconsumedPromises);
if (promise) {
promise.resolve(createIterResult(args, false));
} else {
unconsumedEvents.push(args);
ArrayPrototypePush(unconsumedEvents, args);
}
}

function errorHandler(err) {
finished = true;

const toError = unconsumedPromises.shift();
const toError = ArrayPrototypeShift(unconsumedPromises);

if (toError) {
toError.reject(err);
Expand Down