2012-03-01 21 views
4

これはcodeです:手段、リンク1とリンク2に、順番に、JavaScriptがシングルスレッドの場合、これは何ですか?

// link 1 handler. This must finish in any case before link2 starts 
$('#link1').click(function() { 
    console.log("First Handler"); 
    setTimeout(function() { 
     console.log("Thread???"); 
    }, 2000); 
}); 

// link 2 handler. It starts only when block code of link1's handler finish 
$('#link2').click(function() { 
    console.log("Second Handler");  
});  

$('#link1').click(); 
$('#link2').click(); 

クリックリンク1のハンドラの終了前に開始することはできませんリンク2のハンドラのブロックコード(JSが単一であるので、(私はunderstand何のため)スレッド、およびシステムイベントは同期しています)。

なぜ、console.log("Thread???");は2秒後に印刷されるのですか?私はスレッドのように見ます。また、その動作は同じです...

+3

非同期!=マルチスレッド – zatatatata

答えて

5

程度ジョンResig氏の記事を参照してください、それは単にあなたのconsole.log("Thread???")文を実行します関数を登録setTimeout関数を含む全体の機能を実行します。これは非常に迅速に起こります。あなたは銃器を発射するようにこれを考えてください。あなたは解雇されておらず、あなたは発射準備をしており、2秒のカウントダウンを行っています。

つまり、setTimeout関数は他の関数の実行をブロックせず、強制リンク2を待機させません。リンク1のハンドラが関係する限り、それはうまくいきました.JavaScriptエンジンはlink2のハンドラを実行します。ハンドラは2000msイベントが発生する前に終了します。

+0

この例で何が起きているのかをよく説明した丁寧な回答です! – awe

+0

"つまり、setTimeout関数は他の関数の実行をブロックせず、link2を強制的に待機させますか?いいえ! link2はlink1のsetTimeoutが実行されるのを待っていません! – markzzz

+0

@markzzz - わかりません。明確にすることはできますか? – jmort253

6

シングルスレッド?はい!!説明は、ここでの短い答えではあまりにも包括的であり、前に説明しました。この素晴らしい記事を参照してください:John Resig - How JavaScript Timers Work

編集: "はい!!" :-)

+0

**素晴らしい記事!**イベントとタイマーは、何も実行がブロックされていないときに実行されます。これに基づいて、スケジュールされた実行時にスレッドを占有するものが他にない場合にのみ、時間通りに実行されるタイマーが保証されます。 – awe

2

JavaScriptはシングルスレッドですが、コード実行は非同期にすることができます。ここ

は、実行順序である:

link1 clicked -> link2 clicked -> link1 handler executed -> link2 handler executed -> waiting for less than 2 seconds -> link1 setTimeout event handler logic executed 
+0

link1のハンドラは、シーケンス内の最初のものなので、最初に起動してはいけませんか?私はsetTimeoutの内容については求めていませんが、console.log( "First")とイベントの実際の登録について尋ねています。 – jmort253

+0

申し訳ありませんが、link1のハンドラが最初に起動されますが、setTimeoutメソッドによって中断されているため、実際のロジックは最後に実行されます。 –

+0

先に進んで、あなたの答えを編集して修正してください。私は自分のdownvoteを取り除くでしょう:) – jmort253

1

私はそれを総括しようとすることができると思います。

円形のキューがあり、タイマーにはチェックされる開始/終了(同じものの種類)で評価される瞬間が与えられ、イベントが発生します。

これは愚かな答えのように見えるかもしれませんが、概念的には正しいです。

念入りに作られたwhileループの中に独自のバージョンを実装することができます。

0

Javaスクリプトでスレッドを処理する場合は、HTML5のWebWorkerオブジェクトを使用できます。 WebWorkers http://ejohn.org/blog/web-workers/ハンドラはリンク1のために解雇され

+1

これは、尋ねるが、それはJSエンジンがより現代的なブラウザでより高度になっていることを知って良いです。 – jmort253

0

[スクリプトとして] JavaScriptはシングルスレッドですが、実行するブラウザはOSのマルチスレッド機能を利用できます。

  1. パラメータとして渡されたチャンクの一部をキューsetTimeout()方法を使用:プログラマが必要な場合は

    は、マルチスレッド環境で実行するJavaScriptコードの塊を作るために複数の方法があります。

  2. ActiveX/Applet/Flashコンポーネントの使用:ブラウザ内または別のプロセスとして実行されるネイティブコードです。 Javascriptはこれらのコンポーネントへの制御を取得し、それらのメソッドを呼び出すことができます。

また、すべてのAJAX呼び出しは、ActiveX経由で発生し、コールバックをサポートするため、マルチスレッド化されています。

JavaScriptがシングルスレッドであるという考え方は間違っています...スレッドの作成と操作を制限します。

0

私はこれを助ける!

HTML

<input type="button" value="click me"> 
<input type="text"> 

第1の符号化。

<script> 
    var button = document.body.children[0] 
    var text = document.body.children[1] 

button.onclick = function() { 
    alert('in onclick') 

    text.focus() 

    alert('out onclick') 
    } 

    text.onfocus = function() { 
    alert('onfocus') 
    text.onfocus = null //(*) 
    } 
</script> 

第2コーディング;

<script> 
    var button = document.body.children[0] 
    var text = document.body.children[1] 

/* button.onclick = function() { 
    alert('in onclick') 

    text.focus() 

    alert('out onclick') 
    }*/ 

    text.onfocus = function() { 
    alert('onfocus') 
    text.onfocus = null //(*) 
    } 
    button.onclick = function() { 
     alert(1) 
     setTimeout(function() { text.focus() }, 0) 
     alert(2) 
    } 
</script> 
関連する問題