*JavaScriptでのSleep,Waitの実装について [#f064909e]
**概要 [#ud745b7b]

JavaScriptで「待たせる」という動作をさせるには、~

1. パターン(非推奨)として、~
ループを使った操作に応答しにくい状態の待ち(wait/ビジーウェイト/ループウェイト)~
がありますが、これはまず使わないほうがいいです。ブラウザが応答できなくなるからです。

2 . パターン(推奨)として、~
操作に応答できる状態での待ち(sleep相当)(''推奨'')を実装するには、~
間隔を空けるところで処理のかたまりを関数に分割し、(ステップ分割)、~
「''setTimeout''をかけて次のステップを起動」したり、
「広い間隔で''setInterval''で条件監視を行う」ことで、実現できます。

ブラウザに負担をかけないためには、タイマーを使ったこちらでやるべきです。

-「''ある条件を一定間隔で監視し、条件を満たしたら処理を起動する''」という、~
「''条件監視sleep''」機能を実装してみましょう。

#code(javascript){{
 setViser("グローバル条件", 条件が満たされたとき起動する関数, 監視間隔 ) ;
}}

と設定できる機能を持った関数を実装します。


**動作サンプル [#j33736ca]

-[[動作サンプル>http://f29.aaa.livedoor.jp/~morg/wiki/javascript/sleep_sample.html]]
-[[動作サンプル>http://www.yoshino-tech.com/javascript/sleep_sample.html]]
「ウィンドウの高さが500ピクセル以下になったとき」の条件を監視しています。~
ウィンドウの高さを500以下に操作すると、動作を確認できます。

**サンプルソース [#t55a4263]

#code(JavaScript){{

<html><head><title>JavaScriptのsleep,waitサンプル</title></head>
<body>
条件監視sleepでは、「ウィンドウの高さが400ピクセル以下になったとき」の<br>
条件を監視しています。ウィンドウの高さを400以下に操作すると、<br>
動作を確認できます。<br>
<script type="text/javascript">
<!--
///////////////////////////////////////////////////
//「待ち状態」と言う中で、
// 〜犧遒鳳答しにくい状態での待ち(wait/ビジーウェイト/ループウェイト)
// と、
// ∩犧遒鳳答しやすい状態での待ち(sleep相当)
// の2つがありますが、
// JavaScriptの場合は、
// ループを使うと、操作を受け取りにくい状態の待ち(ビジーウェイト)、
// 間隔の広いsetTimeout,setIntervalを使うと、
// 操作を受け取りやすい状態での待ち(sleep相当)
// というような感じに近くなります。
// また、「ある条件を一定間隔で監視し、条件を満たしたら処理を起動する」
// といった、「条件監視sleep」も実装可能です。

////////////////////////////////////////
//
//  ループ(forまたはwhile)を使ったウェイト関数
//  一定時間ウェイト中は処理を返さない。
//  (ビジー)
function loopWait( timeWait )
{
	var timeStart = new Date().getTime();
	var timeNow = new Date().getTime();
	while( timeNow < (timeStart + timeWait ) )
	{
		timeNow = new Date().getTime();
	}
	return;
}
////////////////////////////////////////////
//
// ■ ある(グローバルな)条件が満たされるまで一定間隔で監視を行い、
//    条件が満たされたら指定された処理を呼び出す関数
//
// ■ setViser( 監視する条件式(文字列) , 
//		条件が満たされとき呼び出す関数(文字列) , 
//		監視間隔)
//    ※条件式の中の変数、関数などはグローバルのものである必要があります。
//	必要に応じてグローバル変数に移しておきます。
//    ・何個も起動できます。
//
var g_IdViser = new Array(); // 監視タイマーのID
var g_NumViser = 0;  	// 監視器のの数
var g_i = 0;		// グローバルカウンタ
function setViser( cond , funcCall , timeVise)
{
	// 条件が満たされれば、タイマーをクリアして関数を呼び出す
	strFunc = "" +
		  "if(" + cond +"){ " + 
		  "clearInterval(g_IdViser[" + g_NumViser + "]);" 
		  + funcCall + ";" + 
		  "}";
	// 監視タイマーをセット ( setInterval)
	g_IdViser[g_NumViser] = setInterval( strFunc , timeVise);
	g_NumViser++;
}

// 処理ステップ1
function step1()
{
	// ループウェイトによる待ち
	alert("ループウェイトで5秒待ちます(ブラウザ応答性低下)");
	loopWait(5000);
	alert("ループウェイト経過しました。");

	// setTimeoutによる待ち
	alert("setTimeOutで5秒待ちます");
	setTimeout( "step2()" , 5000 );
}
function step2()
{
	alert("setTimeOut経過しました");
	alert("条件監視(ウィンドウの高さ<400) 起動します。");
	// ウィンドウの高さが500以下になる という条件を1秒ごとに監視, 
         // 条件を満たしたらstep2を起動
	setViser( "document.body.clientHeight <400", "step3()" , 1000 );
}
// 処理ステップ2
function step3()
{
	alert('条件が満たされました step3起動');
}


// 処理ステップ1起動
step1();
//-->
</script>
</body>
</html>
}}