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 を使うことで本来のロジックに注力できます。