薀蓄
JavaScriptにsleep処理ができないか,その手の質問を良く見かけます。JavaScriptだけで所謂sleep処理はできないのですが,ビジーリードを用いるかJavaScript以外の仕組みを用いれば実現できなくはありません。但し,同期処理や非同期処理,タイマやインターバルを使えば大抵の場合実際に実現したい機能は実装できるはずで,sleep機能を使いたいと思った場合には,先にそちらを検討されることをお勧めします。サンプル
ソース
sleep.pl
#! /usr/local/bin/perl
use CGI;
my $cgi = new CGI();
my $wait = $cgi->param('wait');
$wait =~ s/\D+//g;
$wait /= 1000;
$wait = 10 if ($wait > 10);
sleep($wait);
print "Content-type: text/plain; charset=Shift_JIS\n\n";
print "${wait}.";
1;
JavaScriptSleep.java
function createHttpRequest() {
var httpRequest = null;
if (window.XMLHttpRequest){
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject){
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
}
}
}
return httpRequest;
}
function sleep_server(wait) {
var httpRequest = createHttpRequest();
try {
httpRequest.open('POST','http://'+doument.domain+'/%7elunlumo/cgi-bin/sample/sleep.pl',false);
httpRequest.setRequestHeader("content-type", "application/x-www-form-urlencoded");
httpRequest.send("wait="+escape(wait));
} catch(e) {
alert("request failed.(" + e + ")");
}
}
sleep.js
function createHttpRequest() {
var httpRequest = null;
if (window.XMLHttpRequest){
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject){
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
}
}
}
return httpRequest;
}
function sleep_busy(wait) {
var start = (new Date()).getTime();
while (true) {
if ((new Date()).getTime() >= start + wait * 1) break;
}
}
function sleep_server(wait) {
var httpRequest = createHttpRequest();
try {
httpRequest.open('POST','http://'+document.domain+'/~lunlumo/cgi-bin/sleep.pl',false);
httpRequest.setRequestHeader("content-type", "application/x-www-form-urlencoded");
httpRequest.send("wait="+escape(wait));
} catch(e) {
alert("request failed.(" + e + ")");
}
}
function sleep_applet(wait) {
document.applets["JavaScriptSleep"].sleep_applet(wait);
}
function sleep_test(sleep_type) {
var wait = document.getElementById("wait").value;
switch(sleep_type) {
case 1: sleep_busy(wait); break;
case 2: sleep_server(wait); break;
case 3: sleep_applet(wait); break;
default: break;
}
alert("wakeup");
}
解説
ビジーリード
詳しく解説するまでもないかと思いますが,呼び出し時の時刻を取得し,現在時刻と処理開始時時刻の差が指定された時間を越えるまでひたすらループします。sleep_busy
function sleep_busy(wait) {
var start = (new Date()).getTime();
while (true) {
if ((new Date()).getTime() >= start + wait * 1) break;
}
}
サーバサイド
サーバサイドにsleep処理を実装し,その応答を同期処理で待つ事でsleepを実現します。今回のサンプルでは,サーバ側にはCGIを用意しました。(*1)sleep.pl
#! /usr/local/bin/perl
use CGI;
my $cgi = new CGI();
my $wait = $cgi->param('wait');
$wait =~ s/\D+//g;
$wait /= 1000;
$wait = 10 if ($wait > 10);
sleep($wait);
print "Content-type: text/plain; charset=Shift_JIS\n\n";
print "${wait}.";
1;
sleep_server
function createHttpRequest() {
var httpRequest = null;
if (window.XMLHttpRequest){
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject){
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
}
}
}
return httpRequest;
}
function sleep_server(wait) {
var httpRequest = createHttpRequest();
try {
httpRequest.open('POST','http://'+doument.domain+'/%7elunlumo/cgi-bin/sample/sleep.pl',false);
httpRequest.setRequestHeader("content-type", "application/x-www-form-urlencoded");
httpRequest.send("wait="+escape(wait));
} catch(e) {
alert("request failed.(" + e + ")");
}
}
*1) サンプルとしてアップロードしたスクリプトでは,サーバの負荷を考慮してsleep処理は行わず即時に応答を返しています。
JavaApplet
ページに貼り付けたJavaAppletのメソッドを呼び出してsleepを実現します。JavaScriptSleep.java
package jp.lunlumo.javascript_sleep;
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JApplet;
import javax.swing.JTextField;
public class JavaScriptSleep extends JApplet {
JTextField message;
public void init(){
Container contentPane = getContentPane();
message = new JTextField(10);
setLayout(new BorderLayout());
add(BorderLayout.CENTER,message);
}
public void sleep_applet(long wait) {
message.setText("wait "+wait+"...");
repaint();
try {
Thread.sleep(wait);
} catch(Exception ex) {
}
message.setText("");
repaint();
}
}
sleep_applet
function sleep_applet(wait) {
document.applets["JavaScriptSleep"].sleep_applet(wait);
}