Войти Регистрация
Фронтенд

6. Повтор перевода с экспоненциальной задержкой

Сложная

Перевод в приложении Т‑Банка иногда падает с 503: шлюз перегружен. Повторять сразу нельзя — добьём шлюз. Повторяем с растущей паузой: 100, 200, 400 мс.

Напишите retry(fn, { retries = 3, delay = 100, factor = 2, maxDelay = Infinity }). fn() возвращает промис. При отказе ждём delay * factor ** n мс (n — номер повтора с нуля, не больше maxDelay) и вызываем снова. Всего попыток — retries + 1. Пауза отсчитывается от момента ответа, а не от начала попытки.

Если у ошибки retryable === false (например, «недостаточно средств»), повторять бессмысленно — сразу отклоняем. После последней неудачи отклоняем последней ошибкой.

В работе: Повтор платёжных и сетевых запросов, переподключение WebSocket, опрос статуса операции.

Пример 1: успех с первой попытки

Аргументы теста
["ok"], {"delay": 100, "retries": 3}
Ожидается
{"out": {"at": 20, "ok": true, "value": "перевод проведён"}, "calls": [0]}

Пример 2: две неудачи, потом успех

Аргументы теста
["fail", "fail", "ok"], {"delay": 100, "retries": 3}
Ожидается
{"out": {"at": 360, "ok": true, "value": "перевод проведён"}, "calls": [0, 120, 340]}
Как проверяем Объявите retry — тест вызывает её сам. Таймеры и Date в тестах ненастоящие: время идёт по команде теста, поэтому setTimeout на 5 секунд проверяется мгновенно. Тестов 7: 2 открыты выше, остальные приходят после старта подхода. Лимит — 2 с на тест.
function retry(fn, { retries, delay, factor, maxDelay } = {}) // → Promise
промисытаймерыобработка ошибок

Источник: на задачах Т‑Банка: переводы между картами. Условие пересказано своими словами.

Давали на собеседовании? Ответов пока мало — ваш поможет.