« そういえばバレンタインデー | トップページ | なんとか出来ないかな?<JavaScriptでヒアドキュメント »

2007/02/16

JavaScriptでsleepの実装を試みる

ぼくはまちちゃん!(Hatena) - デブサミ』というところで、
JavaScriptで、sleep
という話が出ているのを見かけ、そういえば1年程前のJavaScript触りはじめの頃に私も調べたなぁ……と懐かしく思い出されました……けれども、あれ、結局方法見付けたんだっけ?
確か、setTimeout()を駆使して実装している例を見つけた記憶があるのですが(当時はさっぱりわからなかった)、いま検索してもそれらしいのが見当たらない……。
で、それならと自分でも考えてみました。
すぐ思いつくのは、単純にループで時刻をポーリングする方法。
function    JSleep_NowaitLoop( sec ) {
    var startTime = (new Date()).getTime() ;
    var stopTime = startTime + Math.floor(1000*sec) ;
    for (;;) {
        var curTime = (new Date()).getTime() ;
        if ( stopTime <= curTime ) break ;
    }
}   //  end of JSleep_NowaitLoop()
でもこれだと、CPUに負荷がかかりすぎて、最近のブラウザだと警告ダイアログが出てしまいそう。
CPU負荷を軽くするため、なんとかイベント待ち状態を作れないかな、と思って、『そうそう、ダイアログ表示中は待ち状態になるや』と、IE で showModalDialog() を使ってモーダルダイアログを呼出し、それが指定時間で閉じるような実装をしてみるものの、
  1. ダイアログを非表示に出来ない(方法がわからない)。
  2. そもそもIEでしか動かない。
ということで、どうも今ひとつ。
で、最後に、ネットワークの伝送速度に着目。
要は、
  1. 適当なファイルをXMLHttpRequestで取得。
  2. XMLHttpRequestは同期モードで使用(Sjax……だっけ?)。
とすることで、ファイル取得時のリクエスト~レスポンスの間、CPUが待ち状態になることを利用しよう、と。
var JSleepDummyFile = './JSleep.js' ;

function    JSleep( sec ) {
    var startTime = (new Date()).getTime() ;
    var stopTime = startTime + Math.floor(1000*sec) ;
    for (;;) {
        var xmlHttpObj = null ;
        if ( typeof ActiveXObject != "undefined" ) {
            var msXml = [ 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP' ] ;
            for ( var ci=0; ci < msXml.length; ci++ ) {
                xmlHttpObj = new ActiveXObject( msXml[ci] ) ;
                if ( xmlHttpObj ) break ;
            }
        }
        else if ( typeof XMLHttpRequest != "undefined" ) {
            xmlHttpObj = new XMLHttpRequest() ;
        }
        if ( !xmlHttpObj ) break ;
        for (;;) {
            var curTime = (new Date()).getTime() ;
            if ( stopTime <= curTime ) break ;
            xmlHttpObj.open( 'GET', JSleepDummyFile + '?time=' + curTime, false ) ;
            xmlHttpObj.send( null ) ;
        }
        break ;
    }
}   //  end of JSleep()
こんな感じ。
伝送速度によって負荷が変わりそうだし誤差も大きいけれど、まぁ一応動作する(WinXP SP2上のIE6(Sleipnir)・Firefox2・Opera9で確認)……もっとも今はナローバンドなので、ブロードバンドでは試せないのだけれど。
動作サンプルはこちら

« そういえばバレンタインデー | トップページ | なんとか出来ないかな?<JavaScriptでヒアドキュメント »

パソコン・インターネット」カテゴリの記事

おもいつき」カテゴリの記事

覚書」カテゴリの記事

コメント

ネットワーク負荷が高まるので嫌な感じです。
あと、firefoxの実装の問題でもあるのですが、NowaitLoopもファイル取得もfirefox全体が止るのも嫌な感じです。

まぁ、もともと無理は承知なわけですが。
#もっとスマートな実装方法あれば教えてください。

| ネットワーク負荷
回線状態がよい環境ほどかかりますからね(苦笑)。
当方の環境(Bフレッツ100M)だと上下併せて800~1000パケット/10秒程度。~1Mbpsってところですかね。

| firefox全体が止る
IEもとまります。

XP上で試すと、
■IE6 SP2:全体停止。複数クライアント起動の場合、実行中のもの以外は動作。
■Firefox2.0.0.1:全体停止。複数クライアント起動の場合、実行中のもの以外も停止。
■Opera9.10:実行中もブラウザ操作可能。
#Firefox、意外といけてない……

ちなみに、XMLHttpRequestを同期モードで実行中には、setTimeoutによる割込もブロックされて(待たされて)しまいます<IE6とFirefox(Operaは未確認)。

firefoxって、ネットワークとかDNS要求とかが複数窓で完全には独立していないように見えますね。スレッド化が中途半端とか?

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: JavaScriptでsleepの実装を試みる:

« そういえばバレンタインデー | トップページ | なんとか出来ないかな?<JavaScriptでヒアドキュメント »

戻るリンク追加

カレンダー

2020年3月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

ココログカレンダーPlus(旧2)

検索


    • Web全体 サイト内
    • 蔵書のISBNを入力して下さい
    • はじめる前
      初級者向け
      上級者向け
      ブログ紹介
      結果を表示

コメントリストツリー化

無料ブログはココログ