« ubunntu 16.04 で chrome でパスワードを聞かれないようにしたい | メイン | マウスクリック無効化(前回の続き) »

2018年6月 4日 (月)

javascript はシングルスレッドだそうです。タイマーを使えば一応解決。

javascript はシングルスレッドだそうです。マルチスレッドではありません。
例えば下記のプログラムは期待通りの動きをしません。

----

<!DOCTYPE html>
<html>
<head>
	<title>global test</title>
	<meta charset="UTF-8">
	<script>
		"use strict";

		// 広域変数
		var testValue=0;
		var message;

		// 初期化関数
		function init() {
			message = document.getElementById("message");


			message.textContent=testValue;
//			alert("start");

			while(testValue < 5){
				sleep(1000);
				message.textContent=testValue;
			}

			message.textContent="end";
		}
	</script>
</head>
<body onload="init()">
	<button onclick="testValue++">click test</button>
	<p id="message"></p>
</body>
</html>

--

http://www3.synapse.ne.jp/wtz/programming/html5/globalTest.html

----

body の button 要素の中身を
<button onclick="testValue++;alert(testValue)">click test</button> に
書き換えてみれば、大域変数 testValue の値は変化していってるのがわかると思います。

これを解決するにはタイマーを使えばよいようです。 script の中を以下のように書き換えます。

----

	<script>
		"use strict";

		// 広域変数
		var testValue=0,timer;
		var message;

		// 初期化関数
		function init() {
			message = document.getElementById("message");


			message.textContent=testValue;
//			alert("start");

			timer = setInterval(tick, 100);
		}

		function tick(){

			if(testValue < 5){
//				sleep(1000);
				message.textContent=testValue;	//debug
			}else{

				message.textContent="end";
				clearInterval(timer);
			}

		}


	</script>

--

http://www3.synapse.ne.jp/wtz/programming/html5/globalTestTimer.html

----

実際のところ、上に書いたような alert 関数を今回も使ってみれば
testValue の値自体は増加し続けているのがわかると思います。
これを避けるには onClick を使用せず getElementById 関数を使って
onclick に関数を設定し、終わったら null を代入しなおせばいいのですが、
それは次回に。(端折って書いてるのでわかりにくくてすいません。)

トラックバック

このページのトラックバックURL:
http://app.synapse-blog.jp/t/trackback/563545/34129153

javascript はシングルスレッドだそうです。タイマーを使えば一応解決。を参照しているブログ:

コメント

コメントを投稿