Ограничитель времени выполнения для асинхронных функций

Соревнуйте Promise исходной операции с Promise таймера и очищайте таймер в finally. Это ограничивает ожидание результата, но само по себе не прекращает выполняющуюся задачу.

Короткий ответ

Что ответить на собеседовании

Соревнуйте Promise исходной операции с Promise таймера и очищайте таймер в finally. Это ограничивает ожидание результата, но само по себе не прекращает выполняющуюся задачу.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо реализовать функцию‑обёртку, принимающую два параметра – асинхронную функцию и лимит времени в миллисекундах. Возвращаемая функция должна выполнять исходную асинхронную задачу, но не дольше указанного ограничения. Требования: • Если работа исходной функции завершается быстрее лимита, обёртка должна вернуть полученный результат. • Если выполнение превышает заданный предел, обёртка должна отклонить промис с сообщением «Превышен лимит времени исполнения».

const originalFn = async (n) => {
  await new Promise(res => setTimeout(res, 100));
  return n * n;
}
withTimeout(originalFn, 50)(5); // rejected: Превышен лимит времени исполнения
withTimeout(originalFn, 150)(5); // resolved: 25

const sumFn = async (a, b) => {
  await new Promise(res => setTimeout(res, 120));
  return a + b;
}
withTimeout(sumFn, 100)(1, 2); // rejected: Превышен лимит времени исполнения
withTimeout(sumFn, 150)(1, 2); // resolved: 3

Ответ

Соревнуйте Promise исходной операции с Promise таймера и очищайте таймер в finally. Это ограничивает ожидание результата, но само по себе не прекращает выполняющуюся задачу.

function withTimeout(fn, ms) {
  return async function (...args) {
    let timer;
    const timeout = new Promise((_, reject) => {
      timer = setTimeout(() => reject(new Error('Превышен лимит времени исполнения')), ms);
    });
    try {
      const work = Promise.resolve().then(() => fn.apply(this, args));
      return await Promise.race([work, timeout]);
    } finally { clearTimeout(timer); }
  };
}

Предполагается конечный неотрицательный ms. Аргументы, this и успешное значение сохраняются; синхронное исключение fn тоже превращается в rejection. Для фактической отмены запрос должен принимать AbortSignal или другой механизм остановки. Долгий синхронный код блокирует даже таймер, поэтому такая обёртка не является прерывателем CPU-работы.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее