Паттерн Module (Модуль), туториал: кеш с WeakMap

Рассмотрим приложение для анализа данных. На входе есть объект с данными, где ключи — это ID пользователей, а значения — массивы с их ответами в опроснике.

Нужно реализовать функцию, которая принимает объект, выполняет определённые «тяжёлые» вычисления для каждого значения и возвращает массив с результатами. К примеру, для каждого пользователя надо вычислить средний балл по его ответам и вернуть массив полученных значений с баллами всех пользователей.

Подходящий инструмент для организации кеша – структура данных WeakMap. WeakMap, как и обычный Map, умеет хранить пары ключ-значение, но ключом в нём может быть только объект:

const obj = { test: 1 };
const value = 2;
const cache = new WeakMap();
cache.set(obj, value);
// cache: [key: {test: 1}, value: 2]

У WeakMap есть такая полезная особенность, что если объект из ключа более не существует в памяти, то значение, привязанное к нему, удаляется из памяти garbage collector-ом; это и можно использовать для организации кеша, который автоматически подчищается, когда закешированные объекты больше не существуют.

Чтобы не выполнять повторно вычисления для одного и того же объекта, можно внутри модуля с логикой вычисления организовать кеш. Тогда при повторном вызове функции результат не будет вычисляться заново, а ранее вычисленное значение просто возьмётся из кеша, и функция отработает быстрее.

Посмотрим на реализацию вычисления массива средних баллов для каждого пользователя с кешированием результата с помощью WeakMap.