Как избежать слишком большого количества вызовов ajax и кэшировать данные json на стороне клиента - PullRequest
4 голосов
/ 09 декабря 2011

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

Существуют ли какие-либо рекомендации относительно способов кэширования этих данных на стороне клиента и проверки, загрузил ли я эти события уже до запуска дополнительных вызовов ajax.

Каков наилучший способ для этого

Ответы [ 3 ]

2 голосов
/ 09 декабря 2011

Как сказал hvgotcodes, MVC-фреймворк поможет;попробуйте backbone.js (например, http://documentcloud.github.com/backbone/),.

В качестве альтернативы, вы можете рассмотреть возможность использования jStorage (http://www.jstorage.info/). Каждый раз, когда вам нужно сделать AJAX-вызов, сначала проверьте, находится ли он в вашем объекте хранения, затемЗапустите вызов AJAX, если это не так. С другой стороны, всякий раз, когда вы завершаете вызов AJAX, сохраняйте результаты в объекте хранилища. Убедитесь, что у вас есть какой-то индекс (идентификатор CalendarEvent), на который можно ссылаться при поиске вхранилище данных. Возможно, вам понадобится добавить какое-то время истечения к данным в вашем хранилище ... временную метку после вызова AJAX и повторно запросить заранее, если он устарел.

1 голос
/ 09 декабря 2011

Это называется MVC.

Вам необходимо построить модель данных для вашего приложения, написать какой-нибудь объект Record, а затем вы сможете определить их статус. Таким образом, ваше приложение будет иметь какую-то модель CalendarEvent, и при загрузке данных с сервера вы будете создавать экземпляры.

Таким образом, при смене представлений вы сначала проверите, есть ли у вас объект модели для этого вида, и, если вы это сделали, вам не нужно загружать его с сервера (если вы не хотите проверять наличие изменений).

Ваша схема не должна быть такой сложной. Если вы загружаете события по Id, вы можете сделать что-то вроде

window.App = {};
window.App.Models = {};

при загрузке записи вы можете поставить

window.App.Models[id] = InstanceOfYourRecord

и так довольно быстро искать записи. Или просто используйте инфраструктуру (например, Sproutcore), которая имеет надежный слой данных.

0 голосов
/ 09 декабря 2011

У меня были похожие проблемы в недавнем проекте.

Концептуально, у меня есть "реальная" модель данных (DM), хранящаяся на сервере, сохраненная в базе данных.

Чтобы сделать жизнь в здравом уме, клиент сохраняет свою собственную локальную модель данных.За пределами клиентской DM весь клиентский код считает, что результаты извлекаются локально.

При чтении данных (GET) с клиентского DM он:

  • проверяет кэш на наличие результатов
  • вызывает соответствующие запросы AJAX, когда кэшированные данные недоступны,затем кэширует результаты.

При изменении данных (POST) через клиентскую DM это:

  • делает недействительным кэш-память соответствующим образом
  • вызывает соответствующие запросы AJAX
  • испускает пользовательское событие jQuery, указывающее, что клиентский DM изменен

Обратите внимание, что этот клиентский DM также:

  • централизует обработку ошибок AJAX
  • дорожекAJAX звонит еще в полете.(Позволяет нам предупреждать пользователей, когда они покидают страницы с несохраненными изменениями.)
  • допускает вставку, фиктивную замену для модульного тестирования, когда все вызовы попадают в локальные данные и полностью синхронны.1034 * Замечания по реализации:
    • Я кодировал это как класс JavaScript с именем DataModel.Поскольку дизайн становится более сложным, имеет смысл дополнительно разделить обязанности по отдельным объектам.
    • Пользовательские события jQuery позволяют легко реализовать шаблон наблюдателя.Клиентские компоненты обновляются с клиентского DM всякий раз, когда он указывает, что данные изменились.
    • JSON в вашем удаленном API помогает упростить код.Мой клиентский DM хранит результаты JSON непосредственно в своем кеше.
    • Аргументы клиентской функции dm включают в себя обратные вызовы, поэтому при необходимости все может быть передано через AJAX: function listAll (contactId, cb) {...}
    • Мой проект допускает только однопользовательский вход.Если внешние стороны могут изменить серверную модель данных, необходимо регулярно запускать какое-то исследование с измененными данными, чтобы гарантировать работоспособность кэша клиента.
    • Для моего приложения несколько клиентских компонентов запрашивают одни и те же данные, когдаполучение клиентом DM измененного события.Это привело к нескольким вызовам AJAX с одной и той же информацией.Я исправил эту проблему с помощью помощника getJsonOnce (), который управляет очередью обратных вызовов клиентских компонентов, ожидающих того же результата.

    Пример функции в моей реализации:

    listAll:
    function( contactId, cb ) {
    
      // pull from cache
      if ( contactId in this.notesCache ) {
        cb( this.notesCache[contactId] );
        return;
      }
    
      // init queue if needed
      this.listAllQueue[contactId] = this.listAllQueue[contactId] || [];
    
      // pull from server
      var self = this;
      dataModelHelpers.getJsonOnce(
        '/teafile/api/notes.php',
        {'req': 'listAll', 'contact': contactId},
        function(resp) { self.notesCache[contactId] = resp; },
        this.listAllQueue[contactId],
        cb
      );
    }
    

    Помощник getJsonOnce () гарантирует, что если несколько клиентских компонентов запрашивают одни и те же (некэшированные) данные, мы отправляем только один AJAX-запрос и сообщаем всем, как только он поступит.

    NotesCache - это простообъект javascript:

    this.notesCache = {};
    
...