Платёжный виджет Альфа-Банка встраивают на сайт магазина. Функцию init(shopId) вызывают из трёх мест: при загрузке страницы, при открытии корзины и при нажатии «Оплатить». Вторая инициализация создаёт второй iframe и дублирует платёж.
Напишите once(fn). Обёртка при первом вызове выполняет fn с теми же this и аргументами и запоминает результат. Последующие вызовы fn не выполняют и возвращают запомненное значение, даже если это undefined.
Если fn бросил исключение, обёртка пробрасывает его, а результат не запоминается: следующий вызов снова пробует выполнить fn.
В работе: init виджета оплаты вызывают из трёх мест страницы, а iframe с формой карты должен быть один.
Пример 1: три вызова — один запуск
[["call", "page"], ["call", "cart"], ["call", "pay"]]
{"log": ["alfa-shop-42:page:1", "alfa-shop-42:page:1", "alfa-shop-42:page:1"], "runs": 1}Пример 2: один вызов
[["call", "pay"]]
{"log": ["alfa-shop-42:pay:1"], "runs": 1}once — тест вызывает её сам. Таймеры и Date в тестах ненастоящие: время идёт по команде теста, поэтому setTimeout на 5 секунд проверяется мгновенно. Тестов 7: 2 открыты выше, остальные приходят после старта подхода. Лимит — 2 с на тест.
function once(fn) // → функция
Источник: на задачах Альфа-Банка: платёжный виджет на сайте магазина. Условие пересказано своими словами.
Ожидаемый ответ не нужен: покажем, что вернула функция.
Здесь появится результат отправки.