This can cache AJAX requests across page-loads with custom max-ages:
FIVE_MINUTES = 5 * 60 * 1000
App.Lib.Cache.promise().maxAge(FIVE_MINUTES).cache('/foo', -> $.get('/foo')).then (results) ->
console.log results
ONE_DAY = 24 * 60 * 60 * 1000 | |
# This is a JSON-based cache which uses `sessionStorage`, so when the user | |
# closes her browser, the cache will be cleared. | |
# | |
# It can only cache POJO's! So be careful! | |
# | |
class Cache | |
constructor: -> | |
@_maxAge = ONE_DAY | |
cache: (key, value) -> | |
cached = @read(key) | |
if cached is null | |
value = value() if typeof value is 'function' | |
@write key, value | |
value | |
else | |
cached | |
maxAge: (maxAge) -> | |
@_maxAge = maxAge | |
this | |
write: (key, value) -> | |
record = { timestamp: Date.now(), value: value, maxAge: @_maxAge } | |
sessionStorage.setItem key, JSON.stringify(record) | |
read: (key) -> | |
cached = sessionStorage.getItem(key) | |
return null if cached is null | |
record = JSON.parse(cached) | |
return null if (Date.now() - record.timestamp) > record.maxAge | |
record.value | |
# This is a more-specific cache which implements a promise-based API (using | |
# jQuery's promises): | |
# | |
# new PromiseCache().cache('/foo', -> $.get('/foo')).then (results) -> | |
# console.log results | |
# | |
class PromiseCache extends Cache | |
cache: (key, fn) -> | |
cached = @read(key) | |
if cached is null | |
fn().then (value) => | |
@write key, value | |
value | |
else | |
$.Deferred().resolve(cached).promise() | |
# Interface with the outer world. | |
App.Lib.Cache = | |
promise: -> | |
new PromiseCache() | |
cache: (key, value) -> | |
new Cache().cache(key, value) |