MrKarton
@MrKarton
Погромист

Как вызывать функцию с теми же аргументами не более одного раза?

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

Функция принимает один параметр - А. И она может вызваться из двух частей программы с одинаковыми значениями А.

Так вот, надо сделать так, чтобы при вызове этой функции два раза с одинаковыми параметрами она выполнилась один раз...

Как вариант - записывать все данные параметров в файл или БД (использую Mongo). Эти параметры всё-равно нужно сохранять, но функция ОБЯЗАТЕЛЬНО должна вызываться один раз. Асинхронные хранилища не подойдут, так как она может вызваться одновременно.

Как такое можно реализовать?
  • Вопрос задан
  • 138 просмотров
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
memoization
это называется «мемоизация» (не от слова «мем», нет : ) Функция запоминает значения аргументов и результат выполнения. Если уже вызывалась с такими аргументами – вернёт «запомненное» значение, не выполняясь ещё раз. Статья на Хабре

В качестве кэша можно использовать объект или WeakMap, если аргумент – объект.

distributed lock
Из вопроса не вполне понятно: в контексте одного выполнения скрипта только один раз, или глобально? Для глобального случая можно использовать какое-то быстрое хранилище, например, Redis, и механизм MutEx ("mutual exclusion" – взаимного исключения), например RedLock.

На пальцах: вот есть аргумент X. То ли вызвать функцию, то ли параллельно уже другой процесс выполняет и скоро будет готовый результат — вопрос.

Генерится случайный ключ. Пара (X, ключ) отправляется в асинхронное хранилище, где если нет ещё сохранённого значения под этот X, ячейка запирается (lock) этим ключом. Тут необходима особенность механизма самого хранилища – в Redis это "NX" – записывать только, если уже нет значения. Это гарантирует, при параллельных запросах, что только чьё-то одно случайное значение запишется. Закон джунглей: первый прибежал — наелся!

Далее надо прочитать записанное значение и получить ключ. Сравнить со своим ранее сгенеренным ключом. Совпали? Значит, это именно мы заперли этот аргумент, и можно выполнить функцию. Не совпали – параллельный процесс выиграл. Просто запросим готовое значение чуть попозже.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы