Using Promises to Cache Static AJAX JSON Data

This article showcases a useful caching strategy for static data that is fetch via AJAX. We will use jQuery to setup a promise and cache the data in the localStorage for subsequent page loads or data loads.

Getting ready

A modern web browser supporting localStorage and JSON. Also, a basic understanding of promises[2] is helpful.

How do it…

Here is the code:

(function($) {
  var oKeyDeferredMap = {};
  function fnReadData(sKey) {
    var sValue = window.localStorage.getItem(sKey);
    return sValue ? JSON.parse(sValue) : sValue;
  function fnWriteData(sKey, oData) {
    var sValue = JSON.stringify(oData);
    window.localStorage.setItem(sKey, sValue);
  $.cachedAjaxPromise = function(sUrl, oAjaxOptions) {
    var oDeferred = oKeyDeferredMap[sUrl];
    var sValue;
    if (!oDeferred) {
      oDeferred = new jQuery.Deferred();
      oKeyDeferredMap[sUrl] = oDeferred;
      sValue = fnReadData(sUrl);
      if (sValue) {
      if (!oAjaxOptions) {
        oAjaxOptions = {};
      $.extend(oAjaxOptions, {
        error: function(oXHR, sTextStatus, sErrorThrown) {
          console.log('customer info request failed: ' + sErrorThrown);
        success: function(oData) {
          // making assumption that data is JSON
          fnWriteData(sUrl, oData);
      $.ajax(sUrl, oAjaxOptions);
    return oDeferred.promise();

Here is how to use the code:

oPromise = $.cachedAjaxPromise('/someURL').done(function(o) {

Here is a codepen demoing the code:

See the Pen HtJcD by Matt Snider (@mattsnider) on CodePen.

How it works…

The code snippet adds a new function to jQuery cachedAjaxPromise which should be passed a URL returning a static JSON and returns a promise that will be resolved with the JSON object. The function checks the local storage for a value stored at the key of the url. If a value exists, then resolve the promise. If the value doesn’t exist, then fetch it from the server, cached into localStoage, and the promise is resolved or rejected based on the AJAX response cycle. All cached values are marshalled and unmarshalled using the JSON infrastructure to and from strings. Lastly, the jQuery deferred object, is also cached, to prevent duplicate AJAX requests or calls to the localStorage when promises for the same url are created.

To use cachedAjaxPromise, provide a url and chain a done or then function. The success callback provided will be pass the JSON data. If you look at the example pen, you will see that the first time the pen is loaded (or after you clear the localStorage) it takes about two seconds (simulated AJAX request), but subsequent page loads resolve the data in millisecond (from localStorage). You may pass a second argument, as the configuration options to pass into $.ajax, but the success and error functions will be overwritten for use with the promise system.

This a very simple example that is dependent on modern web browser technology. If you need to support legacy browsers, then you may need a polyfill the JSON[3] library and localStorage[4].


  1. jQuery Deferred
  2. Promises in Wicked Detail
  3. jQuery JSON Polyfill
  4. PersistJs - a localStorage Polyfill