mofmof.js の Future でシンプルに非同期処理を記述する
以下は、画像を3つ読み込み全て読み込み後に canvas でまとめて描画するコードです。
http://mofmof-js.googlecode.com/svn/trunk/test/base.js.htm に行き、コンソールに以下のコードを貼り付けると動作します。
(function() {
var images = [
"http://www.google.co.jp/images/nav_logo102.png",
"http://k.yimg.jp/images/top/sp/logo.gif",
"http://www.bing.com/fd/s/a/sw3.png"
];
var canvas = document.createElement("canvas");
canvas.width = 800;
canvas.height = 800;
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
// 3個の画像全てを読み込み終わったら drawCanvas を呼びます
var future = drawCanvas.every(images.length);
images.each(function(url, index) {
// mm.Class.Image に future を bind すると
// 画像の読み込み完了/失敗のたびに
// future.pass(node) や future.miss(node) を呼びます
new mm.Class.Image(url, future, index);
});
function drawCanvas(result) { // { ok: Boolean,
// args: NodeArray,
// state: Number }
if (result.ok) { // ok = 完了
result.args.each(function(node) {
ctx.drawImage(node, node.index * 200, // sx
node.index * 200); // sy
});
}
}
})();
全ての画像の読み込みを待たず、読み込みが終わったものから canvas で次々描画するには以下のようにします。
(function() {
var images = [
"http://www.google.co.jp/images/nav_logo102.png",
"http://k.yimg.jp/images/top/sp/logo.gif",
"http://www.bing.com/fd/s/a/sw3.png"
];
var canvas = document.createElement("canvas");
canvas.width = 800;
canvas.height = 800;
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
// 3個の画像全てを読み込み終わったら drawCanvas を呼びます
// var future = drawCanvas.every(images.length);
// 画像を1つ読み込む毎に drawCanvas を呼びます。これを3回くり返します
// 全て読み込み終了で mm.nop (何もしない関数) を呼びます
var future = mm.nop.every(images.length, drawCanvas);
images.each(function(url, index) {
// mm.Class.Image に future を bind すると
// 画像の読み込み完了/失敗のたびに
// future.pass(node) や future.miss(node) を呼びます
new mm.Class.Image(url, future, index);
});
function drawCanvas(result) { // { ok: Boolean,
// args: NodeArray,
// state: Number }
// if (result.ok) { // ok = 完了
// result.args.each(function(node) {
// ctx.drawImage(node, node.index * 200, // sx
// node.index * 200); // sy
// });
// }
// 100(継続中) または 200(読み込み完了) で描画します
if (result.state < 400) {
// 最後のimg要素(読み込みが終わったimg要素)を参照します
var node = result.args.tail();
ctx.drawImage(node, node.index * 200, // sx
node.index * 200); // sy
}
}
})();
このように、Future と連携する機能をもった mm.Class.Image を使うことで本来のロジックに注力できます。