Я использую цикл for..of над forEach(). forEach() не будет ожидать каждого промиса отдельно:
Код: Выделить всё
// timerDemo.ts
export async function executeInOrderWithDelay(
fns: (() => Promise)[],
delayMs = 1000,
): Promise {
for (const fn of fns) {
await fn()
await new Promise((r) => setTimeout(r, delayMs))
}
}
У меня возникли проблемы в Jest-UnitTests, имитирующем setTimeout() с использованием FakeTimers Jest:
Код: Выделить всё
import { executeInOrderWithDelay } from './TimerDemo'
describe('executeInOrderWithDelay', () => {
afterEach(() => {
jest.useRealTimers()
})
test('executes functions in order with specified delay', async () => {
jest.useFakeTimers()
const calls: number[] = []
const fns = [
jest.fn(() => {
calls.push(1)
return Promise.resolve()
}),
jest.fn(() => {
calls.push(2)
return Promise.resolve()
}),
jest.fn(() => {
calls.push(3)
return Promise.resolve()
}),
]
executeInOrderWithDelay(fns, 1000)
// first should be invoked immediately
expect(fns[0]).toHaveBeenCalledTimes(1)
expect(fns[1]).not.toHaveBeenCalled()
// advance to allow loop to proceed to second
jest.advanceTimersByTime(1000)
expect(fns[1]).toHaveBeenCalledTimes(1)
expect(fns[2]).not.toHaveBeenCalled()
// advance to allow loop to proceed to third
jest.advanceTimersByTime(1000)
expect(fns[2]).toHaveBeenCalledTimes(1)
expect(calls).toEqual([1, 2, 3])
})
})
Код: Выделить всё
FAIL test/TimerDemo.spec.ts
executeInOrderWithDelay
✕ executes functions in order with specified delay (7 ms)
● executeInOrderWithDelay › executes functions in order with specified delay
expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
32 | // advance to allow loop to proceed to second
33 | jest.advanceTimersByTime(1000)
> 34 | expect(fns[1]).toHaveBeenCalledTimes(1)
| ^
35 | expect(fns[2]).not.toHaveBeenCalled()
36 |
37 | // advance to allow loop to proceed to third
Подробнее здесь: https://stackoverflow.com/questions/798 ... faketimers
Мобильная версия