test_runner: clean up promisified interval generation · nodejs/node@83cdf17

11

'use strict';

2233

const {

4-

ArrayPrototypeAt,

54

ArrayPrototypeForEach,

65

ArrayPrototypeIncludes,

76

DatePrototypeGetTime,

@@ -14,9 +13,8 @@ const {

1413

ObjectDefineProperty,

1514

ObjectGetOwnPropertyDescriptor,

1615

ObjectGetOwnPropertyDescriptors,

17-

Promise,

16+

PromiseWithResolvers,

1817

Symbol,

19-

SymbolAsyncIterator,

2018

SymbolDispose,

2119

globalThis,

2220

} = primordials;

@@ -35,14 +33,15 @@ const {

3533

},

3634

} = require('internal/errors');

373536+

const { addAbortListener } = require('internal/events/abort_listener');

37+3838

const { TIMEOUT_MAX } = require('internal/timers');

39394040

const PriorityQueue = require('internal/priority_queue');

4141

const nodeTimers = require('timers');

4242

const nodeTimersPromises = require('timers/promises');

4343

const EventEmitter = require('events');

444445-

let kResistStopPropagation;

4645

// Internal reference to the MockTimers class inside MockDate

4746

let kMock;

4847

// Initial epoch to which #now should be set to

@@ -423,62 +422,36 @@ class MockTimers {

423422

}

424423425424

async * #setIntervalPromisified(interval, result, options) {

426-

const context = this;

427425

const emitter = new EventEmitter();

426+427+

let abortListener;

428428

if (options?.signal) {

429429

validateAbortSignal(options.signal, 'options.signal');

430430431431

if (options.signal.aborted) {

432432

throw abortIt(options.signal);

433433

}

434434435-

const onAbort = (reason) => {

436-

emitter.emit('data', { __proto__: null, aborted: true, reason });

437-

};

438-439-

kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation;

440-

options.signal.addEventListener('abort', onAbort, {

441-

__proto__: null,

442-

once: true,

443-

[kResistStopPropagation]: true,

435+

abortListener = addAbortListener(options.signal, () => {

436+

emitter.emit('error', abortIt(options.signal));

444437

});

445438

}

446439447440

const eventIt = EventEmitter.on(emitter, 'data');

448-

const callback = () => {

449-

emitter.emit('data', result);

450-

};

441+

const timer = this.#createTimer(true,

442+

() => emitter.emit('data'),

443+

interval,

444+

options);

451445452-

const timer = this.#createTimer(true, callback, interval, options);

453-

const clearListeners = () => {

454-

emitter.removeAllListeners();

455-

context.#clearTimer(timer);

456-

};

457-

const iterator = {

458-

__proto__: null,

459-

[SymbolAsyncIterator]() {

460-

return this;

461-

},

462-

async next() {

463-

const result = await eventIt.next();

464-

const value = ArrayPrototypeAt(result.value, 0);

465-

if (value?.aborted) {

466-

iterator.return();

467-

throw abortIt(options.signal);

468-

}

469-470-

return {

471-

__proto__: null,

472-

done: result.done,

473-

value,

474-

};

475-

},

476-

async return() {

477-

clearListeners();

478-

return eventIt.return();

479-

},

480-

};

481-

yield* iterator;

446+

try {

447+

// eslint-disable-next-line no-unused-vars

448+

for await (const event of eventIt) {

449+

yield result;

450+

}

451+

} finally {

452+

abortListener?.[SymbolDispose]();

453+

this.#clearInterval(timer);

454+

}

482455

}

483456484457

#setImmediate(callback, ...args) {

@@ -490,38 +463,31 @@ class MockTimers {

490463

);

491464

}

492465493-

#promisifyTimer({ timerFn, clearFn, ms, result, options }) {

494-

return new Promise((resolve, reject) => {

495-

if (options?.signal) {

496-

try {

497-

validateAbortSignal(options.signal, 'options.signal');

498-

} catch (err) {

499-

return reject(err);

500-

}

501-502-

if (options.signal.aborted) {

503-

return reject(abortIt(options.signal));

504-

}

505-

}

466+

async #promisifyTimer({ timerFn, clearFn, ms, result, options }) {

467+

const { promise, resolve, reject } = PromiseWithResolvers();

468+469+

let abortListener;

470+

if (options?.signal) {

471+

validateAbortSignal(options.signal, 'options.signal');

506472507-

const onabort = () => {

508-

clearFn(timer);

509-

return reject(abortIt(options.signal));

510-

};

511-512-

const timer = timerFn(() => {

513-

return resolve(result);

514-

}, ms);

515-516-

if (options?.signal) {

517-

kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation;

518-

options.signal.addEventListener('abort', onabort, {

519-

__proto__: null,

520-

once: true,

521-

[kResistStopPropagation]: true,

522-

});

473+

if (options.signal.aborted) {

474+

throw abortIt(options.signal);

523475

}

524-

});

476+477+

abortListener = addAbortListener(options.signal, () => {

478+

reject(abortIt(options.signal));

479+

});

480+

}

481+482+

const timer = timerFn(resolve, ms);

483+484+

try {

485+

await promise;

486+

return result;

487+

} finally {

488+

abortListener?.[SymbolDispose]();

489+

clearFn(timer);

490+

}

525491

}

526492527493

#setImmediatePromisified(result, options) {