Использование функции memoize с помощью underscore.js

Я пытаюсь кэшировать результат из ajax-вызова с помощью функции memoize из Underscore.js. Я не уверен в своей реализации. Также как восстановить данные кэшированного результата с помощью ключа. Ниже приведена моя реализация:

Код Javascript:

var cdata = $http
.get(HOST_URL + "/v1/report/states")
.success(function(data) {
    //put the result in the angularJs scope object. 
    $scope.states = data;
});

//store the result in the cache.
var cachedResult = _.memoize(
    function() {
        return cdata;
    }, "states");

Я использую memoize для сохранения результата ajax правильно. Также после того, как он помещен в кеш, как получить на основе ключа. i'e 'states'.

Ответ 1

Понятно, как работает _.memoize, он принимает функцию, которая должна быть memoized как первый аргумент и кэширует результат возврата функции для данного параметра. В следующий раз, если memoized функция вызывается с тем же аргументом, она будет использовать кешированный результат, и время выполнения для этой функции можно избежать. Поэтому очень важно сократить время вычисления.

Как уже упоминалось, вышеупомянутая функция фибоначчи, которую она memoized работает отлично, отлично, поскольку аргумент имеет примитивный тип.

Проблема возникает, когда вы должны memoize функцию, которая принимает объект. Чтобы решить эту проблему, _.memoize принимает необязательный аргумент hashFunction, который будет использоваться для ввода хэша. Таким образом, вы можете уникально идентифицировать свои объекты своими собственными хеш-функциями.

Реализация по умолчанию _.memoize (с использованием хэш-функции по умолчанию) возвращает первый аргумент как есть - в случае JavaScript он вернет [Object object].

Так, например,

var fn = function (obj){ some computation here..}
var memoizedFn = _.memoize(fn);

memoizedFn({"id":"1"}) // we will get result, and result is cahced now

memoizedFn({"id":"2"}) // we will get cached result which is wrong

почему default имеет функцию в _.memoize - это функция (x) {return x}

проблему можно избежать, передав хеш-функцию

_.memoize(fn, function(input){return JSON.stringify(input)});

Это была реальная помощь для меня, когда я использовал _.memoize для функции, которая работала над аргументами массивов.

Надеюсь, это поможет многим людям в их работе.

Ответ 2

_.memoize принимает функцию:

var fibonacci = _.memoize(function(n) {
  return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);
});

Вы должны понимать, что это просто дополнительная функция-обертка, которая делает функцию, которую вы передаете в качестве аргумента, более умной (добавляет к ней дополнительный объект отображения).

В приведенном выше примере функция, которая вычисляет число Фибоначчи, оборачивается с помощью _.memoize. Поэтому при каждом вызове функции (fibonacci(5) или fibonacci(55555)) переданный аргумент сопоставляется с возвращаемым значением, поэтому, если вам нужно вызвать еще один раз fibonacci(55555), ему не нужно вычислять его снова. Он просто выбирает это значение из того объекта сопоставления, который _.memoize предоставил внутри.

Ответ 3

Если вы используете Angular.js $http, вы, вероятно, просто хотите передать {cache : true} в качестве второго параметра методу get.

Для хранения значений с использованием пар "ключ-значение" вы можете использовать $ cacheFactory, как описано в других ответах, например здесь. В основном:

var cache = $cacheFactory('cacheId');
cache.put('states', 'value');
cache.get('states');