3. sleep のない言語 JavaScript どうやって実現するか? function sleep(msec) { // CPU_100% var t = (new Date()).getTime()-(-msec); while ( (new Date()).getTime() < t ) {} } function sleep(msec) { // LiveConnect Packages.java.lang.Thread.sleep(msec); }
4. クロスブラウザで sleep を実現(無理矢理) function sleep(msec) { try { // for IE window.showModalDialog( "javascript:document.write('<script>" + "window.setTimeout(function(){window.close()}," + msec + ");<"script>');"); } catch (e) { try { // for Firefox, Opera with LiveConnect Packages.java.lang.Thread.sleep(msec); } catch (e) { // for Safari and others var limit = (new Date()).getTime() - (-msec); while ((new Date()).getTime() < limit) {} } } }
5. 1秒ごとに表示したい(よくある間違い) <script> function sleep(msec) { var t = (new Date()).getTime() - (-msec); while ( (new Date()).getTime() < t ); } function init() { var body = document.body; sleep(1000); body.innerHTML += "<h1>Hello!</h1>"; sleep(1000); body.innerHTML += "<h2>Hello?</h2>"; sleep(1000); body.innerHTML += "<h3>Hello!?</h3>"; }; </script> <body onload="init()"></body>
17. yield を含む関数は Generator になる function generator() { for (var i = 1; i <= 1000; i++) { document.title = i; yield; } } var g = generator(); // [object Generator] // まだ document.title は変更されない
18. Generator#nextで次の yield まで実行戻る function generator() { for (var i = 1; i <= 1000; i++) { document.title = i; yield; } } var g = generator(); // [object Generator] g.next(); // document.title = 1; g.next(); // document.title = 2; g.next(); // document.title = 3;
19. uncaught exception: [object StopIteration] function generator() { for (var i = 1; i <= 1000; i++) { document.title = i; yield; } } var g = generator(); for (var j = 1; j <= 998; j++) { g.next() } g.next(); // document.title = 999; g.next(); // document.title = 1000; g.next(); // Error: uncaught exception: // [object StopIteration]
20. Generator#close function generator() { for (var i = 1; i <= 1000; i++) { document.title = i; yield; } } var g = generator(); for (var j = 1; j <= 998; j++) { g.next() } g.next(); // document.title = 999; g.next(); // document.title = 1000; g.close();
21. yield の引数が next() の戻り値になる function generator() { for (var i = 1; i <= 1000; i++) { document.title = i; yield (i); } } var g = generator(); var r; r = g.next(); // r = 1; r = g.next(); // r = 2; r = g.next(); // r = 3;
22. next() の戻り値をチェックしてきちんと終了 function generator() { for (var i = 1; i <= 1000; i++) { document.title = i; yield (i); } yield (-1); // 終了条件 } var g = generator(); var r; do { r = g.next() } while (r > 0); // 1...1000 g.close();
23. 巨大ループ中で setTimeout(f, 0) が呼べる! function generator() { for (vari = 1; i <= 1000; i++) { document.title = i; yield true; } yield false; } function driveGenerator(g) { if (g.next()) { // yield true? var f = function(){ driveGenerator(g) }; setTimeout(f, 0); } else { g.close(); // yield false } } driveGenerator( generator() );
30. HTML5 Web Workers API main.html worker.js (1) var worker = new Worker(“worker.js”); ワーカースレッドの作成 (2) worker.postMessage(”hello”); (3) onmessage = function(e) { var result = e.data + ”!”; (4) postMessage(result); (5) worker.onmessage = function(e) { // DOM 更新処理 window.alert(e.data);
31. ワーカスレッドを呼び出す UIスレッド worker.html <title>HTML5 Web Workers</title> <script> var worker = new Worker("worker.js"); worker.onmessage = function(e){ document.body.innerHTML += e.data; } worker.postMessage("hello"); </script>
32. ワーカスレッドの定義(重たい処理を分離) worker.js function sleep(msec) { var t = (new Date()).getTime() - (-msec); while ( (new Date()).getTime() < t ); } //↓ワーカ側でメッセージを受信したときの処理 onmessage = function(e) { sleep(1000); postMessage("<h1>" + e.data + "!</h1>"); }