使用 Node.js 定时器模块


🌐 Working with Node.js timers modules

一旦你启用模拟计时器,node:timersnode:timers/promises 模块,以及来自 Node.js 全局上下文的计时器就会被启用:

🌐 Once you enable mocking timers, node:timers, node:timers/promises modules, and timers from the Node.js global context are enabled:

注意:import { setTimeout } from 'node:timers' 这样的解构函数目前不被此 API 支持。

import assert from 'node:assert';
import { test } from 'node:test';
import nodeTimers from 'node:timers';
import nodeTimersPromises from 'node:timers/promises';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', async (context) => {
 const globalTimeoutObjectSpy = context.mock.fn();
 const nodeTimerSpy = context.mock.fn();
 const nodeTimerPromiseSpy = context.mock.fn();
 // Optionally choose what to mock
 context.mock.timers.enable({ apis: ['setTimeout'] });
 setTimeout(globalTimeoutObjectSpy, 9999);
 nodeTimers.setTimeout(nodeTimerSpy, 9999);
 const promise = nodeTimersPromises.setTimeout(9999).then(nodeTimerPromiseSpy);
 // Advance in time
 context.mock.timers.tick(9999);
 assert.strictEqual(globalTimeoutObjectSpy.mock.callCount(), 1);
 assert.strictEqual(nodeTimerSpy.mock.callCount(), 1);
 await promise;
 assert.strictEqual(nodeTimerPromiseSpy.mock.callCount(), 1);
});const assert = require('node:assert');
const { test } = require('node:test');
const nodeTimers = require('node:timers');
const nodeTimersPromises = require('node:timers/promises');
test('mocks setTimeout to be executed synchronously without having to actually wait for it', async (context) => {
 const globalTimeoutObjectSpy = context.mock.fn();
 const nodeTimerSpy = context.mock.fn();
 const nodeTimerPromiseSpy = context.mock.fn();
 // Optionally choose what to mock
 context.mock.timers.enable({ apis: ['setTimeout'] });
 setTimeout(globalTimeoutObjectSpy, 9999);
 nodeTimers.setTimeout(nodeTimerSpy, 9999);
 const promise = nodeTimersPromises.setTimeout(9999).then(nodeTimerPromiseSpy);
 // Advance in time
 context.mock.timers.tick(9999);
 assert.strictEqual(globalTimeoutObjectSpy.mock.callCount(), 1);
 assert.strictEqual(nodeTimerSpy.mock.callCount(), 1);
 await promise;
 assert.strictEqual(nodeTimerPromiseSpy.mock.callCount(), 1);
});

在 Node.js 中,node:timers/promisessetInterval 是一个 AsyncGenerator,并且也被此 API 支持:

🌐 In Node.js, setInterval from node:timers/promises is an AsyncGenerator and is also supported by this API:

import assert from 'node:assert';
import { test } from 'node:test';
import nodeTimersPromises from 'node:timers/promises';
test('should tick five times testing a real use case', async (context) => {
 context.mock.timers.enable({ apis: ['setInterval'] });
 const expectedIterations = 3;
 const interval = 1000;
 const startedAt = Date.now();
 async function run() {
 const times = [];
 for await (const time of nodeTimersPromises.setInterval(interval, startedAt)) {
 times.push(time);
 if (times.length === expectedIterations) break;
 }
 return times;
 }
 const r = run();
 context.mock.timers.tick(interval);
 context.mock.timers.tick(interval);
 context.mock.timers.tick(interval);
 const timeResults = await r;
 assert.strictEqual(timeResults.length, expectedIterations);
 for (let it = 1; it < expectedIterations; it++) {
 assert.strictEqual(timeResults[it - 1], startedAt + (interval * it));
 }
});const assert = require('node:assert');
const { test } = require('node:test');
const nodeTimersPromises = require('node:timers/promises');
test('should tick five times testing a real use case', async (context) => {
 context.mock.timers.enable({ apis: ['setInterval'] });
 const expectedIterations = 3;
 const interval = 1000;
 const startedAt = Date.now();
 async function run() {
 const times = [];
 for await (const time of nodeTimersPromises.setInterval(interval, startedAt)) {
 times.push(time);
 if (times.length === expectedIterations) break;
 }
 return times;
 }
 const r = run();
 context.mock.timers.tick(interval);
 context.mock.timers.tick(interval);
 context.mock.timers.tick(interval);
 const timeResults = await r;
 assert.strictEqual(timeResults.length, expectedIterations);
 for (let it = 1; it < expectedIterations; it++) {
 assert.strictEqual(timeResults[it - 1], startedAt + (interval * it));
 }
});

AltStyle によって変換されたページ (->オリジナル) /