前回に引き続き,Wikipediaから緯度経度を取得しGoogle Maps上にプロットするアプリケーションを作っていきます。
今回は透過的なキャッシュの仕組みを入れるのと,
完成コードは以下のようになります。
透過的なキャッシュ
キャッシュのための領域として,
localStorageは同期的に値を取得やセットをできますが,
前回は,
リスト1
$.getJSON(url).
next(function (data) {
// ...
});
はじめに,
リスト2
withCache('wikipediajson', function () { return $.getJSON(url) }).
next(function (data) {
// ...
});
withCache(key,fun);はkeyをキャッシュキーにしてfunが返すデータをキャッシュする関数で,
withCache関数を作るために,
リスト3
function foobar () {
var d = new Deferred;
setTimeout(function () { d.call('done!') }, 0);
return d;
}
foobar().next(function (r) {
alert(r); //=> 'done!'
});
これでDeferredオブジェクトを返す関数を作ることができます。
withCacheでは,
リスト4
function withCache (key, fun) {
var d = new Deferred();
var val = localStorage.getItem(key);
if (val) {
next(function () {
d.call(eval(val));
});
} else {
fun().next(function (data) {
try {
localStorage.setItem(key, uneval(data));
} catch (e) {
localStorage.clear(); // キャッシュが溢れた
localStorage.setItem(key, uneval(data));
}
d.call(data);
});
}
return d;
}
localStorageにデータがあるときはnext()関数で呼び出しを非同期化した上でcall()メソッドを呼んでいます。JavaScriptで非同期処理を同期化することは決してできないのは先に言及したとおりですが,
この同期処理をnext()で非同期にするということをせずに,
localStorageにデータがないときは,