2009-09-01 10 views
13

、これら二つの間に何が違うのがあります:最近、私は関数を呼び出すためにsetTimeout(0)を使用する場合、コードはのみ動作状況に出くわしたので、私は尋ねたMyFunction()vs window.setTimeout( 'MyFunction()'、0)? JavaScriptでは

// call MyFunction normal way 

MyFunction(); 

// call MyFunction with setTimeout to 0 // 

window.setTimeout('MyFunction()', 0); 

理由でした。 私の理解では、setTimeout(0)は、遅延を設定しないので直接関数を呼び出すのとまったく同じです。しかし、私がコード内でどのように動作するかを見ると、setTimeout(0)が最後に実行されるようです。

誰かが実際にsetTimeout(0)が他の関数呼び出しの残りの順番で実際に呼び出される方法を明確にすることはできますか?

+1

http:// stackoverflow。com/questions/779379/why-does-settimeoutfn-0-sometimes-help –

答えて

17

setTimeout()は、常にJavaScriptのブロックを実行のためにキューに入れます。提供された遅延によって決定されるのは、いつ実行されるかの問題です。 遅延が0のsetTimeout()を呼び出すと、JavaScriptインタプリタが現在ビジー状態(現在の関数を実行中)であることが認識され、インタプリタは現在の呼び出しスタックが空になったら実行されるスクリプトブロックをスケジュールしますキューに入れられている他のスクリプトブロックもあります)。

呼び出しスタックが空になるまでに時間がかかる可能性があります。そのため、実行が遅れることがあります。これは主に、単一のウィンドウコンテキストでのJavaScriptのシングルスレッドの性質によるものです。

完全性のために、MyFunction()はすぐにその関数を実行します。キューイングは行われません。

PSJohn Resig has some useful notes on how the JavaScript timing mechanism works

PPS:setTimeout(fn()、0)を使用したときにのみコードが「うまくいくように見える」理由は、ブラウザが現在の呼び出しスタックが完了したときにのみDOMを更新できるためです。したがって、次のJavaScriptブロックはDOMの変更を認識しますが、これはあなたのケースでは可能です。 setTimeout()コールバックは、常に新しいコールスタックを作成します。

3

タイムアウトは、ページが完全に読み込まれたときにのみ開始され、プレーンな「MyFunction()」は処理されるとすぐに実行されると思います。

+1

これは正しいです。推測する必要はありません。 –

+1

@Mariusがテストページを設定して試してみましょう - インライン関数はページの最下位で実行され、先頭の火で宣言されたsetTimeout(0)が発生します。 –

+0

あなたは正しいと思って、コメントを削除しましたが、あなたがそれを見た前ではありませんでした。 – Marius

0

タイマーは、現在のスレッドが完了すると実行を試みます。これは、window.setTimeout()を呼び出す場所によって異なります。それがjavascriptタグにあり、関数内ではない場合は、javascriptタグの終わりに達すると呼び出されます。たとえば、次のように

<html> 
<script type="text/javascript"> 
setTimeout(function(){alert("hello")},0); 
var d=Number(new Date())+1000; 
while(Number(new Date())<d){ 

} 
alert("hi"); 
</script> 
</html> 

イベント・occuringから得られる関数内でのsetTimeoutを呼び出す場合は、イベントハンドラ関数が戻るまで、例えばonloadイベント、それが待機します:

<html> 
<script type="text/javascript"> 
document.addEventListener("mousedown",function(){ 
    setTimeout(function(){alert("hello")},0); 
    var d=Number(new Date())+1000; 
    while(Number(new Date())<d){ 

    } 
    alert("hi"); 
}, true); 
</script> 
</html> 

それは不可能です別のスレッドが実行されている間にJavaScript内のあるスレッドを待機させる。イベントリスナーは、現在のスレッドが実行を開始するまで待機します。

唯一の例外はWeb Workersですが、別のファイルで実行されますが、それらの間で通信する唯一の方法はイベントリスナーを使用することです。したがって、別のファイルが動作している間にメッセージを送信することはできますが、そのメッセージが完了するまで、または手動でメッセージをチェックします。

+0

あなたが言うことはすべて、一般的な意味で正しいです(JavaScriptはシングルスレッドです)が、スクリプトブロックの最後にヒットしたときではなく、ページが読み込まれるとsetTimeout(0)が発生します。 –

関連する問題