ResultsCache

by Julian

CSS

body {
    font: 14px/1.4em Helvetica, Arial;
    padding: 10px;
}

JavaScript

// Utility function to display log output
function logOutput(output) {
    $('body').append("<b>&gt</b> " + output + "<br />");
}

/**
 * ResultsCache definition
 */
var ResultsCache = function(computationFunction, cacheKeyGenerator) {
    this._cache = {};
    this._computationFunction = computationFunction;
    if (cacheKeyGenerator)
        this._cacheKeyGenerator = cacheKeyGenerator;
};

ResultsCache.prototype.compute = function() {
    // try to retrieve computation from cache
    var cacheKey = this._cacheKeyGenerator.apply(this, arguments);
    var promise = this._cache[cacheKey];

    // if not yet cached: start computation and store promise in cache 
    if (!promise) {
        var deferred = $.Deferred();
        promise = deferred.promise();
        this._cache[cacheKey] = promise;

        // perform the computation
        var args = Array.prototype.slice.call(arguments);
        args.push(deferred.resolve);
        this._computationFunction.apply(null, args);
    }

    return promise;
};

// Default cache key generator (works with Booleans, Strings, Numbers and Dates)
// You will need to create your own key generator if you work with Arrays etc.
ResultsCache.prototype._cacheKeyGenerator = function(args) {
    return Array.prototype.slice.call(arguments).join("|");
};


// Example: add two numbers
var addingMachine = new ResultsCache(function(a, b, resultHandler) {
    // simulate rather long calculation time by using a 1s timeout
    setTimeout(function() {
        logOutput("Performing computation: adding " + a + " and " + b);
        var result = a + b;
        resultHandler(result);
    }, 1000);
});

addingMachine.compute(2, 4).then(function(result) {
    logOutput("result: " + result);
});

addingMachine.compute(1, 1).then(function(result) {
    logOutput("result: " + result);
});

addingMachine.compute(2, 4).then(function(result) {
    logOutput("result: " + result);
});

/*

// Example: perform and cache ajax calls
var ajaxCache = new...