Шаблон кэша с обратными вызовами - PullRequest
0 голосов
/ 13 сентября 2011

У меня есть класс, который обрабатывает данные. Другие классы могут давать ему свои значения, и класс данных будет заполнять их.

Это выглядит так:

class Data

  constructor : ->
    @products = null

  populateProducts : (callback)=>
    ajaxCall (data)=>
      @products = data
      callback()

  allProducts : (list)=>
    if @products?
      list = @products
    else
      @populateProducts => allProducts list

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

Один способ, которым я попытался, был следующим:

  productsCheck : (callback)=>
    if @products?
      callback()
    else
      @populateProducts => products callback

Используя этот метод, я мог бы упростить все продукты:

 allProducts : (list)=>
     @productsCheck => list = @products

В конце я ищу технику, которая делает: «если продуктов не существует, заполняют их из базы данных». Возможно, я подумал, что это может быть известная модель, поэтому, если это так, то информация о нем также приветствуется.

Ответы [ 2 ]

4 голосов
/ 13 сентября 2011

Подчеркивание имеет концепцию _.memoize

, которая будет кэшировать результат вызова функции для идентификатора (т. Е. Первого аргумента).

Memoization - это простой в реализации шаблон.

var memoize = function _memoize(f) {
  var cache = {};
  return function _intercept(arg) {
    if (cache[arg]) return cache[arg];
    return (cache[arg] = f.apply(this, arguments));
  }
};

Вы должны настроить этот шаблон, чтобы он работал асинхронно с обратными вызовами.

Для полноты здесь есть _.memoize code:

_.memoize = function(func, hasher) {
  var memo = {};
  hasher || (hasher = _.identity);
  return function() {
    var key = hasher.apply(this, arguments);
    return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
  };
};

Кажется, что Underscore принимает hasher в качестве второго аргумента, который будет генерировать уникальный ключ на основе аргументов.(по умолчанию используется функция идентификации подчеркивания).

Кажется, также используется hasOwnProperty, поэтому вы можете использовать раздражающие ключи, такие как toString и valueOf, которые будут отмечать truey при проверке свойств.

1 голос
/ 13 сентября 2011

Поскольку вы загружаете @products асинхронно, и каждый метод объекта должен (потенциально) ожидать загрузки @products, каждый метод объекта является асинхронным и должен возвращать свой результат в обратный вызов. Там нет никакого способа обойти это; Вы не можете сделать асинхронный код JS синхронным. allProducts не может просто вернуть значение.

Вот что вы должны сделать: во-первых, измените populateProducts, чтобы он не совершал Ajax-вызов, если он не должен:

populateProducts : (callback) =>
  if @products?
    callback()
  else ajaxCall (data) =>
    @products = data
    callback()

Затем просто запустите каждый метод, который использует @products, с вызовом @populateProducts, например так:

allProducts : (callback) =>
  @populateProducts =>
    callback @products

firstProduct: (callback) =>
  @populateProducts =>
    callback @products[0]

# ...
...