@nqounetです。
昨日はイベント駆動版が手元になかったのでコールバック版でしたが、イベント駆動版も晒します。
とりあえずイベント駆動版のソース
ソースコードはこんな感じです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
(function($, global, undefined){
'use strict';
var lscache,
Mustache,
processing = {},
generateCacheKey = function(path){
return 'fetched:' + path;
},
fetchTemplate = function(path){
console.debug('fetchTemplate');
var key = generateCacheKey(path);
$.get(path, function(template){
console.debug('run $.get');
lscache.set(key, template, 1);
delete processing[key];
$(global).triggerHandler(key); // fetch完了イベントを発行
});
},
renderOnEvent = function(e){
console.debug('renderOnEvent');
var args = Array.prototype.slice.apply(e.data);
render.apply(this, args);
},
render = function(path, args, cb){
console.debug('render');
var key = generateCacheKey(path);
var template = lscache.get(key);
if (template) {
return cb(Mustache.render(template, args));
}
else {
$(global).one(key, arguments, renderOnEvent);// fetch完了時のイベントを受信した時にもう一度実行する
if (!processing[key]) {
processing[key] = true;
fetchTemplate(path);// keyになるfetchをしていない場合はfetchする
}
}
},
setVars = function(){
// localize
lscache = global.lscache || console.error('not ready `lscache.js`. hint : `bower install lscache`.');
Mustache = global.Mustache || console.error('not ready `mustache.js`. hint : `bower install mustache`.');
},
init = function(){
setVars();
return {
'render': render
};
};
global.templates = init();
}(jQuery, this));
|
該当部分は日本語でコメントを書いていますが、この書き方が有用なのかについてはイマイチわかりません。
コールバックの嫌なところ
コールバックがあるとものすごく自由なんですよね。
で、その自由と引き換えに、メソッドの名前に非常に迷うことになります。
例えばfetchTemplateに対して、取得したテンプレートファイルでレンダリングするコールバックを渡すとrenderTemplateのように動作するわけです。
実際の仕事は、AJAXでgetするだけなのですが、その後のコールバックでレンダリングさせる、というふうに考えながらプログラミングしていると、名前に違和感を感じてしまうんですよ。
かと言って、renderTemplateという名前にするのは論外です。
猛者の方々はこの辺の気持ちをどう始末しているんでしょうか?
キャッシュがなければAJAXでテンプレートファイルを取得する
使い方としては、テンプレートファイルのURLと、テンプレートに反映させるオブジェクト、そしてコールバックです。
…結局コールバックは必要でした。
いや、今回のような場合なら、jQueryオブジェクトを渡せばコールバックがなくてもほどほどに使えますが、なんとなく微妙じゃないですかね?
1
2
3
4
5
|
// コールバックの場合
templates.render('templates/sns.mst', fbObj, function(content){ $this.append(content) });
// jQueryオブジェクトの場合は、引数の順序はこんな感じ?メソッド名も変えておかないとねぇ
templates.renderTo($this, 'templates/sns.mst', fbObj);
|
で、考え始めると、jQueryでメソッドチェーンできるようにすればいいんだよ、という感じになります。
1
|
$.templates('templates/sns.mst', fbObj).appendTo($this);
|
まあ、書けるかどうかも判断できませんが。
非同期のメソッドチェーン(=コールバック?)
この辺をうまく書こうとすると、jQuery.Deferredの世界へ足を踏み入れる必要があるんでしょうね。
「メソッドチェーンに見えて実はコールバック」だったら、非同期を意識しないでプログラミングできると思います。
というか、何故コールバックが必要かというと、非同期の処理が終わらないと次の処理ができないからです。
今までのプログラム(同期的プログラミング?)は、基本的には上から下、左から右という風に流れが決まっていました。
しかし、非同期の場合はそれが保証できないので、保証するための仕組みがコールバック、というふうに理解しています。
まあ、その部分は同期的に処理される、という事ですね。
queueはどう?
jQueryにはqueueというメソッドがあります。
そのイメージのとおり、jobを順番待ちさせる感じで使えるのですが、サンプルがアニメーションばかりなので、実際の使い所がよくわかりません。
ソースを見てみれば何かわかるのかもしれませんが、読み解ける自信がありません。
イベント駆動
イベント駆動というと、クリックした時、とか、マウスオーバーした時、のようにユーザーの操作によって動作するイメージですが、それだけではありません。
例えばコールバックの中に、動作が完了した、というイベントを発行すれば、そのイベントによって続きの動作が可能になります。
ただ、そればかりをやっているとGOTOを使っている気分になります。
非常に微妙です。