web-dev-qa-db-ja.com

次の行を実行する前に5秒間待ってください

以下のこの機能は、私が望むようには機能しません。 JSの初心者であることで私はその理由を理解することができません。

newState-1であるかどうかをチェックする前に5秒間待つ必要があります。

現時点では、待っているのではなく、ただちにチェックします。

function stateChange(newState) {
  setTimeout('', 5000);

  if(newState == -1) {
    alert('VIDEO HAS STOPPED');
  }
}
224
copyflake

あなたが提供するコールバック関数にあなたのコードを入れなければなりませんsetTimeout

function stateChange(newState) {
    setTimeout(function () {
        if (newState == -1) {
            alert('VIDEO HAS STOPPED');
        }
    }, 5000);
}

他のコードはすぐに実行されます。

259
Joseph Silber

あなたは本当にこれをするべきではありません 、タイムアウトの正しい使い方はOPの問題や、しばらくしてから何かを実行したいだけの場合には正しいツールです。 Joseph Silberは、彼の答えの中でそれをよく示しています。ただし、本番環境以外の場合に 本当に とメインスレッドを一定期間ハングさせたい場合は、これでうまくいきます。

function wait(ms){
   var start = new Date().getTime();
   var end = start;
   while(end < start + ms) {
     end = new Date().getTime();
  }
}

次の形式で実行します。

console.log('before');
wait(7000);  //7 seconds in milliseconds
console.log('after');

長時間実行されるブロッキング操作(つまり、高価なDOM操作)を中心に非同期操作の組み合わせをシーケンス処理するための単純なテストケースを作成していたため、ここに到着しました。それはその仕事にはぴったりです、それで私は私がここに到着した他の誰のためにも同じようなユースケースでそれを掲示すると思いました。それでも、whileループ内でDate()オブジェクトを作成しています。実行時間が長いと、GCに負担がかかる可能性があります。しかし、私は十分に強調することはできません、 これはテストにのみ適しています。実際の機能を構築するためには、Joseph Silberの回答を参照してください。

132
Mic

これは新しい async/await という構文を使った解決策です。

ブラウザのサポート をチェックしてください。これはECMAScript 6で導入された新機能です。

ヘルパー関数:

const delay = ms => new Promise(res => setTimeout(res, ms));

使用法:

const yourFunction = async () => {
  await delay(5000);
  console.log("Waited 5s");

  await delay(5000);
  console.log("Waited an additional 5s");
};

この方法の利点は、コードが同期コードのように見え、動作するようになることです。

65
Etienne Martin

このような遅延機能を使用してください。

var delay = ( function() {
    var timer = 0;
    return function(callback, ms) {
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
})();

使用法:

delay(function(){
    // do stuff
}, 5000 ); // end delay

クレジットはユーザーCMSに行きます。 ユーザーが入力を止めるまで.keyup()ハンドラーを遅らせるにはどうすればいいですか?

32
Kai Noack

あなたはただJavaScriptで5秒間休止しようとするべきではありません。それはうまくいきません。今から5秒後に実行するようにコードの関数をスケジュールすることができますが、後で実行したいコードを関数に入れる必要があり、その関数の後の残りのコードはすぐに実行され続けます。

例えば:

function stateChange(newState) {
    setTimeout(function(){
        if(newState == -1){alert('VIDEO HAS STOPPED');}
    }, 5000);
}

しかし、次のようなコードがあるとします。

stateChange(-1);
console.log("Hello");

console.log()ステートメントはすぐに実行されます。タイムアウトがstateChange()関数で発生するまで待ちません。 JavaScriptの実行を所定の時間だけ一時停止することはできません。

代わりに、遅延を実行したいコードはすべてsetTimeout()コールバック関数内にある必要があります(またはその関数から呼び出される)。

ループして「一時停止」しようとした場合は、基本的にはJavascriptインタプリタを一定期間「ハング」させることになります。 Javascriptは単一のスレッドでのみコードを実行するため、ループしているときは他に何も実行できません(他のイベントハンドラを呼び出すことはできません)。したがって、ある変数が変更されるのを待っているループは、その変数を変更するために他のコードを実行することができないため、決して機能しません。

30
jfriend00

あなたが async関数にいるなら あなたは単に一行でそれをすることができます:

console.log(1);
await new Promise(resolve => setTimeout(resolve, 3000)); // 3 sec
console.log(2);

Notice 、targetがNodeJSの場合、これを使用するほうが効率的です(事前定義されたpromisified setTimeout関数です)。

await setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](3000) // 3 sec
14
Shl

ミリ秒単位で待つためにこのような関数を作成するための最良の方法は、この関数は引数で提供されるミリ秒を待つでしょう:

function waitSeconds(iMilliSeconds) {
    var counter= 0
        , start = new Date().getTime()
        , end = 0;
    while (counter < iMilliSeconds) {
        end = new Date().getTime();
        counter = end - start;
    }
}
7

これを試して:

//the code will execute in 1 3 5 7 9 seconds later
function exec() {
    for(var i=0;i<5;i++) {
        setTimeout(function() {
            console.log(new Date());   //It's you code
        },(i+i+1)*1000);
    }
}
6
Steve Jiang

Joseph Silberの answer に基づいて、もう少し一般的なようにします。

あなたはあなたの機能を持っているでしょう(質問に基づいてそれを作成しましょう):

function videoStopped(newState){
   if (newState == -1) {
       alert('VIDEO HAS STOPPED');
   }
}

そして、あなたは待機機能を持つことができます:

function wait(milliseconds, foo, arg){
    setTimeout(function () {
        foo(arg); // will be executed after the specified time
    }, milliseconds);
}

最後には、

wait(5000, videoStopped, newState);

それは解決策です、私はむしろ待機関数で引数を使用したくない(foo();の代わりにfoo(arg);だけを持つ)が、それは例のためです。

3
Sylhare

私はEdgeやIEからPCゲームを実行するためにそれを使いました。そして7秒後にIE Edgeを自己終了します。

FirefoxとGoogle Chromeは、この方法でゲームを開始するのには使用できません。

<html<body>
<a href="E:\game\game.exe" name="game" onmouseout="waitclose(7000);"> game
<img src="game.jpg" width="100%" height="97%" ></a>
<script>
function waitclose(ms){
 var start = new Date().getTime();var end=start;
 while(end < start + ms) {end = new Date().getTime();}
window.open('', '_self', ''); window.close();
}
</script>
</body></html>
1
user4565320