勉強中のメモです。
HTML開発でAjaxなどJavaScriptを活用しようとすると、コールバックを使った非同期処理が活躍します。
ここで一つ疑問に思ったのが、「内部実装としてはイベント処理ってどうしてるんだろう?」という点です。
Win32API開発経験者としては、「やっぱりイベントメッセージのループとかあるのかなぁ・・・」とか、「Ajaxとか非同期I/Oが発生すると、そこだけ別スレッドで処理して、処理が終わるなどのイベントが発生したら、元スレッドのイベントキューにpostしたりしてやりとりしてんのかなぁ」とか。
ということで、調査中の参考リンク、簡単なデモコードなどの仮置き場です。
JavaScriptのDOMイベントの分かりやすい概説
JavaScriptからDOMノードに任意のイベントハンドラを設定し、イベントを発生させるサンプルの解説
JavaScriptのイベントループの内部実装の解説系
html5rocksより:
SpiderMonkeyのThreadSafetyメモ
Javaでコールバック地獄を解決するためのアプローチ:
Javaでのマルチスレッドプログラミング
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> div { margin: 5px; padding: 5px; border: 1px solid red; } </style> <script> // [start : http://stackoverflow.com/questions/2490825/how-to-trigger-event-in-javascript の丸パクリ] // Add an event listener document.addEventListener("name-of-event", function(e) { console.log(e.detail); // Prints "Example of an event" }); // Create the event var event = new CustomEvent("name-of-event", { "detail": "Example of an event" }); // Dispatch/Trigger/Fire the event document.dispatchEvent(event); // [end] // stopPropagation() のテスト用グローバルフラグ window.div2_stop_propagate = false; function stop_propagete() { window.div2_stop_propagate = true; } function test() { // DOM要素が構築された後でないとgetElementById()でDOMノードを取り出せないので、body#onloadイベントで呼び出す。 var p1 = document.getElementById("p1"); p1.addEventListener("click", function(e) { console.log("p1-click", e); }); var div1 = document.getElementById("div1"); div1.addEventListener("click", function(e) { console.log("div1-click", e); }); var div2 = document.getElementById("div2"); div2.addEventListener("click", function(e) { console.log("div2-click", e); if (window.div2_stop_propagate) { // テスト用グローバルフラグがセットされていれば、stopPropagation()を呼んでみる。 e.stopPropagation(); } }); var div3 = document.getElementById("div3"); div3.addEventListener("click", function(e) { console.log("div3-click", e); }); } </script> </head> <body onload="test()"> <div id="div1"> div1 <div id="div2"> div2 <div id="div3"> div3 <p id="p1">click</p> </div> </div> </div> <hr> <input type="button" value="stop at div2" onclick="stop_propagete()"> </body> </html>
Firefox30での実行結果:
Chrome34での実行結果:
IE11での実行結果: