如何在客户端避免过多的ajax调用和缓存json数据

时间:2011-12-09 00:19:32

标签: javascript jquery ajax caching rich-internet-application

我有一个日历应用程序,它使用ajax和json结果加载所有事件数据。问题是我有不同的观点,现在我必须在我改变观点时重新调用服务器。

是否有任何建议我可以在客户端缓存此数据,并检查我是否已经在启动更多ajax调用之前加载了这些事件。

最佳做法是什么?

3 个答案:

答案 0 :(得分:2)

像hvgotcodes所说,MVC框架会有所帮助;例如,试试backbone.js(http://documentcloud.github.com/backbone/)。

或者,您可能需要考虑使用jStorage(http://www.jstorage.info/)。每次需要进行AJAX调用时,首先检查它是否在您的存储对象中,然后运行AJAX调用(如果不是)。另一方面,无论何时完成AJAX调用,都要将结果存储在存储对象中。确保在数据存储中查找时需要引用某种索引(CalendarEvent id)。可能想要在存储中的数据中添加某种“过期时间”......在AJAX调用之后的时间戳,如果它已经过时则重新请求。

答案 1 :(得分:1)

它被称为MVC。

您需要为您的应用程序构建数据模型,编写某种Record对象,然后您可以确定它们的状态。因此,您的应用程序将具有某种CalendarEvent模型,当您从服务器加载数据时,您将实例化实例。

因此,在更改视图时,您首先要检查是否有该视图的模型对象,如果有,则不需要从服务器加载它(除非您要检查更改)。

您的方案不需要那么复杂。如果您按ID加载事件,则可以执行类似

的操作
window.App = {};
window.App.Models = {};

加载记录时可以放

window.App.Models[id] = InstanceOfYourRecord

这样就可以快速查找记录了。或者只使用具有健壮数据层的框架(如Sproutcore)。

答案 2 :(得分:0)

我在最近的一个项目中遇到过类似的问题。

从概念上讲,我将“真实”数据模型(DM)保存在服务器上,并持久保存到数据库中。

为了让生活更加健全,客户端会保留自己的本地数据模型。在客户端DM之外,所有客户端代码都认为它在本地提取结果。

从客户端DM读取数据(GET)时:

  • 检查缓存中是否存在现有结果
  • 在缓存数据不可用时调用适当的AJAX查询,然后缓存结果。

通过客户端DM更改数据(POST)时:

  • 根据需要使缓存无效
  • 调用适当的AJAX查询
  • 发出指示客户端DM已更改的自定义jQuery事件

请注意,此客户DM也是:

  • 集中管理AJAX错误
  • 跟踪仍在飞行中的AJAX通话。 (让我们在离开未保存更改的页面时警告用户。)
  • 允许用于单元测试的插入式虚拟替换,其中所有调用都访问本地数据并且完全同步。

实施说明:

  • 我将其编码为名为DataModel的JavaScript类。随着设计变得越来越复杂,进一步细分分离对象的责任是有意义的。
  • jQuery的自定义事件可让您轻松实现观察者模式。只要客户端组件指示数据已更改,客户端组件就会自动从客户端DM更新。
  • 远程API中的JSON有助于简化代码。我的客户端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 = {};