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

发布于 2024-12-20 08:02:41 字数 157 浏览 2 评论 0原文

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

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

对此的最佳实践是什么?

I have a calendar application and it loads all of the event data using ajax and json results. the issue is that i have different view and right now i have to re call the server when i change views.

Is there any recommendation for ways i can cache this data on the client side and check if i have loaded these events already before firing off more ajax calls.

What is the best practice for this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扮仙女 2024-12-27 08:02:41

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

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

Like hvgotcodes said, an MVC framework would help; try backbone.js (http://documentcloud.github.com/backbone/), for instance.

Alternatively, you might want to consider using jStorage (http://www.jstorage.info/). Every time you need to make an AJAX call, check first if it's in your storage object, then run the AJAX call if it isn't. On the other end, whenever you finish an AJAX call, store the results in the storage object. Make sure you have some kind of index (a CalendarEvent id) to reference when looking it up in the data store. Might want to add some kind of "expire time" to the data in your storage, too ... a timestamp after the AJAX call, and re-request up front if it's out of date.

轮廓§ 2024-12-27 08:02:41

这就是所谓的MVC。

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

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

你的计划不需要那么复杂。如果您按 Id 加载事件,则可以执行类似于

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

加载记录时放置

window.App.Models[id] = InstanceOfYourRecord

操作,这样查找记录的速度相当快。或者只使用具有强大数据层的框架(如 Sproutcore)。

It's called MVC.

You need to construct a data model for you application, write some sort of Record objects, and then you can determine their status. So your application would have some sort of CalendarEvent model, and when you load data from the server, you would instantiate instances.

So when changing views, you would first check to see if you had the model object for that view, and if you did, you wouldn't need to load it from the server (unless you want to check for changes).

Your scheme doesn't need to be that complicated. If you load events by Id, you can do something like

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

when you load a record you could put

window.App.Models[id] = InstanceOfYourRecord

and that way its pretty fast to look for records. Or just use a framework (like Sproutcore) that has a robust data layer.

帅气称霸 2024-12-27 08:02:41

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

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

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

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

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

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

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

请注意,此客户端 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 = {};

I had similar issues on a recent project.

Conceptually, I have the "real" data model (DM) kept on the server, persisted to a database.

To make life sane, the client keeps its own local data model. Outside of the client DM, all the client code thinks it's pulling results locally.

When reading data (GET) from the client DM it:

  • checks the cache for existing results
  • invokes appropriate AJAX queries when cached data is not available, then caches the results.

When changing data (POST) via the client DM it:

  • invalidates the cache as appropriate
  • invokes appropriate AJAX queries
  • emits custom jQuery event indicating client DM changed

Note that this client DM also:

  • centralizes AJAX error handling
  • tracks AJAX calls still in-flight. (Lets us warn users when leaving pages with unsaved changes).
  • allows a drop-in, dummy replacement for unit testing, where all the calls hit local data and are completely synchronous.

Implementation notes:

  • I coded this as a JavaScript class called DataModel. As the design becomes more complex, it makes sense to further break-down the responsibilities in to separate objects.
  • jQuery's custom events let you easily implement the observer pattern. Client components update themselves from the client DM whenever it indicates data has changed.
  • JSON in your remote API helps simplify the code. My client DM stores the JSON results directly in its cache.
  • The client dm function arguments include call-backs so everything can naturally be passed along via AJAX when needed: function listAll( contactId, cb ) { ... }
  • My project only allowed single user logins. If outside parties can change the server datamodel, some sort of has-data-changed probe should be fired regularly to ensure the client cache is still valid.
  • For my app, multiple client components would request the same data when receiving a client DM changed event. This resulted in multiple AJAX calls with the same info. I fixed this problem with a getJsonOnce() helper, which manages a queue of client component call-backs awaiting the same result.

Example function in my implementation:

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
  );
}

The getJsonOnce() helper makes sure that if multiple client components request the exact same (uncached) data, that we only send out a single AJAX request and inform everyone once it comes in.

The notesCache is just a simple javascript object:

this.notesCache = {};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文