JavaScript って sleep 関数ないの?
JavaScript には sleep 関数がないらしい。ちょっとビックリ。
なにを思ったか、ハノイの塔を解く手順をアニメ(?)にしてみたら面白いのではないかと思って、JavaScript でコードを書いてたときのこと。コード中に、1回処理をしたらちょっと sleep してから次の処理に進む、という処理を入れたくて sleep 関数を探したけど、どこにもないではないですか。
はじめは、内部でビジーウェイトで sleep していたんだけど、途中経過が描画されず、結果しか表示されなかった。原因は、JavaScript で画面が再描画されるタイミングは、イベントが発生して、そのイベントのハンドラがが終了したあと、だということ。
最終的に setTimeout() を使って、描画イベントをどんどん積んでいく方法にして、うまく表示されるようになった。
/* 円盤は書くのが面倒くさそうなので、まずは数字で。*/ var Rod1 = new Array(); // 棒A (スタック) var Rod2 = new Array(); // 棒B (スタック) var Rod3 = new Array(); // 棒C (スタック) var RodArray = {"a": Rod1, "b": Rod2, "c": Rod3}; // ループするときに使う var N = 0; // 円盤の個数 var T = 1; var WaitMSec = 33; // 描画間隔 /* ハノイの塔のロジック */ function hanoi(n, rod1, rod2, rod3) { if (n > 0) { hanoi(n - 1, rod1, rod3, rod2) /* タイマーイベント設定 */ setTimeout( function() { rod3.push(rod1.pop()); for (var key in RodArray) { for (var i = N - 1; i >= 0; i--) { var data = " "; if (RodArray[key][i] != undefined) { data = RodArray[key][i]; } document.getElementById(key + i).childNodes.item(0).data = data; } } }, WaitMSec * T ); T += 1; hanoi(n - 1, rod2, rod1, rod3); } } /* * 数字を表示させるテーブルを生成 */ function createTable(n) { var body = document.getElementsByTagName("body").item(0); var table = document.createElement("table"); var thr = document.createElement("tr"); var tha = document.createElement("th"); tha.appendChild(document.createTextNode("A")); var thb = document.createElement("th"); thb.appendChild(document.createTextNode("B")); var thc = document.createElement("th"); thc.appendChild(document.createTextNode("C")); thr.appendChild(tha); thr.appendChild(thb); thr.appendChild(thc); table.appendChild(thr); for (var i = 1; i <= n; i++) { var tda = document.createElement("td"); tda.appendChild(document.createTextNode(i)); tda.id = "a" + (n - i); var tdb = document.createElement("td"); tdb.appendChild(document.createTextNode(" ")); tdb.id = "b" + (n - i); var tdc = document.createElement("td"); tdc.appendChild(document.createTextNode(" ")); tdc.id = "c" + (n - i); var tr = document.createElement("tr"); tr.data = " "; tr.appendChild(tda); tr.appendChild(tdb); tr.appendChild(tdc); table.appendChild(tr); } body.appendChild(table); } /* start */ N = 5; for (var i = N; i > 0; i--) { Rod1.push(i); } createTable(N); hanoi(N, Rod1, Rod2, Rod3);
でも、思っていた程動きが面白くなかったので、放置。JavaScript は日頃ほとんど使わないので、よくない書き方の所がいっぱいありそう。