На экране входа в Яндекс ID кнопка «Прислать код ещё раз» шлёт SMS. Одна SMS стоит денег, поэтому за сессию разрешаем 3 отправки, а на четвёртом нажатии показываем «Попробуйте через час».
Напишите addLimit(fn, limit, onLimit). Обёртка вызывает fn с теми же аргументами и возвращает её результат, пока вызовов было меньше limit. Дальше fn не вызывается, обёртка возвращает undefined и, если передан onLimit, вызывает его на каждое лишнее нажатие.
У обёртки есть метод reset(): счётчик снова с нуля. Его зовём после успешного входа.
В работе: Повторная отправка кода: 3 SMS по 2,5 ₽, четвёртое нажатие показывает таймер вместо запроса.
Пример 1: три отправки и одна лишняя
3, true, [["call", "+7 916"], ["call", "+7 916"], ["call", "+7 916"], ["call", "+7 916"]]
["sms:+7 916", "ret:ok:+7 916", "sms:+7 916", "ret:ok:+7 916", "sms:+7 916", "ret:ok:+7 916", "limit", "ret:undefined"]
Пример 2: onLimit на каждое лишнее нажатие
1, true, [["call", "a"], ["call", "b"], ["call", "c"]]
["sms:a", "ret:ok:a", "limit", "ret:undefined", "limit", "ret:undefined"]
addLimit — тест вызывает её сам. Таймеры и Date в тестах ненастоящие: время идёт по команде теста, поэтому setTimeout на 5 секунд проверяется мгновенно. Тестов 6: 2 открыты выше, остальные приходят после старта подхода. Лимит — 2 с на тест.
function addLimit(fn, limit, onLimit) // → функция с методом reset()
Источник: Яндекс, задача addLimit из репозитория кандидата с задачами собеседований, 2024. Условие пересказано своими словами.
Ожидаемый ответ не нужен: покажем, что вернула функция.
Здесь появится результат отправки.