Rate Limiter

Реализуйте функцию rateLimiter(fn, limit, ms), которая принимает:

  • fn — функцию, которую нужно вызывать;
  • limit — максимальное количество вызовов функции за указанный интервал времени;
  • ms — интервал времени в миллисекундах.

Функция должна возвращать новую обёртку, которая не позволит вызывать fn чаще, чем limit раз за ms.

Если за интервал времени ms уже произошло limit вызовов, то очередной вызов все равно должен будет отработать, когда появится ближайшая возможность.

Пример

function apiRequest(id) { return `Запрос ${id} выполнен`; } const limitedApi = rateLimiter(apiRequest, 3, 600); setTimeout(() => console.log(limitedApi(1)), 0); // 0 setTimeout(() => console.log(limitedApi(2)), 100); // 100 setTimeout(() => console.log(limitedApi(3)), 200); // 200 setTimeout(() => console.log(limitedApi(4)), 300); // 600 setTimeout(() => console.log(limitedApi(5)), 500); // 700 setTimeout(() => console.log(limitedApi(6)), 1000); // 1000 setTimeout(() => console.log(limitedApi(7)), 1100); // 1100 setTimeout(() => console.log(limitedApi(8)), 1200); // 1300 setTimeout(() => console.log(limitedApi(9)), 1300); // 1600

Схематично вызовы можно показать так:

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 -----------------
  • Верхняя строчка — сотни миллисекунд от первого вызова, например 06 — 600 мс, 14 — 1400 мс
  • Вторая строчка — вызовы limitedApi
  • Третья строчка — фактические вызовы apiRequest

В любом окне ширине 600 мс (например, на схеме с 700 по 1300) происходит не более 3 вызовов apiRequest.