Pull to refresh

cache-js. функция кэширования

Reading time 3 min
Views 21K
Некоторое время назад возникла необходимость кэшировать ответы сервера на клиенте. Сразу оговорюсь, что я знаю про кэш браузеров, но это был не мой случай. Не долго думая я начал дополнять код для загрузки данных, что бы перед отправкой запроса на сервер, проверялось нет ли уже результата с таким запросом.

Для наглядности приведу пример до:
function loadData(url, fn) {
	ajax.get(url, function (err, result) {
		//тут обрабатываем ответ и возвращаем результат
		var data = '...';
		
		fn(null, data);
	});
}

и после:
var cache = {};

function loadCacheData(url, fn) {
	var cacheData = cache[url];
	
	//проверяем кэш
	if (cacheData) {
		fn(null, cacheData);
	} else {
		ajax.get(url, function (err, result) {
			//тут обрабатываем ответ и возвращаем результат
			var data = '...';
			
			//сохраняем в кэш
			cache[url] = data;
			
			fn(null, data);
		});
}


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

Это положило начало к написанию простой функции обертки которая превращала бы loadData в loadCacheData.
Выглядеть это должно примерно так:
function loadData(url, fn) {
	ajax.get(url, function (err, result) {
		//тут обрабатываем ответ и возвращаем результат
		var data = '...';
		
		fn(null, data);
	});
}

var loadCacheData = cache(loadData);

Полученная таким способом функция «loadCacheData» должна сама кэшировать результат, а так же предоставлять функционал по управлению кэша.

Через некоторое время удалось реализовать более менее работающую версию функции «cache». Все исходники доступны на github.

Что позволяет делать эта функция:

1. Сброс кэша.
var loadCacheData = cache(loadData);
loadCacheData.clearCache();


2. Устанавливать время жизни для кэша. По умолчанию устанавливает на 1 год.
var loadCacheData = cache({ expire: 10 * 1000 }, loadData);


3. Установка максимального размера кэша (сколько ответов хранить в кэше). По умолчанию 10.
var loadCacheData = cache({ max: 10 }, loadData);


4. Выбор способа хранения кэш. По умолчанию «app».
app — хранить кэш в памяти.
local — хранить кэш в localStorage и доступен между всеми страницами сайта.
var loadCacheData = cache({ storage: 'local' }, loadData);

При установке «local» опционально можно установить «cacheKey» — имя ключа в localStorage где храниться кэш.

5. Установка собственного хранилища для кэша.
var loadCacheData = cache({ storage: new MyCacheStorage() }, loadData);

В этом случае MyCacheStorage() должен реализовывать три метода:
«get(key, fn);» — метод выбирает результаты из кэша по ключу.
«set(key, val, fn);» — метод устанавливает значение к кэш.
«clear(fn);» — метод сбрасывает кэш.
«fn» — функция обратного вызова, принимающая первым аргументом «ошибку», вторым «результат» (если он есть) выполнения функции.

Использование «cache-js» накладывает одно ограничение, функции, результат которых необходимо «закэшировать», должны подчиняться правилу: «Последний параметр должен быть функцией обратного вызова!».

TODO:
  • Сейчас функция «cache» добавляется в глобальную область, планируется вынести в отдельную
  • Добавить кэш с использованием sessionStorage
  • Глобальные опции, например что бы полностью отключить кэш при разработке
  • Поддержка старых браузеров. В данный момент используются методы parse/stringify объекта JSON, getItem/setItem/removeItem объекта localStorage
  • !? Порт на nodejs (под вопросом)


Примеры с использованием доступны в репозитории
Tags:
Hubs:
+6
Comments 8
Comments Comments 8

Articles