2013-05-13 16 views
17

私はJavascriptの非同期関数とコールバックを把握しようとしています。Javascriptは同期(ブロッキング)または非同期(非ブロッキング)でデフォルトでは

私はいくつかの場所で読んでいるコールバック関数のコンセプトに悩まされています。コードの逐次実行(主にjqueryコンテキストのアニメーションなど)と特にNodejsのコンテキスト内のいくつかの場所があります。非同期で並列実行し、コードのブロックを避けるために使用されます。

このトピックのいくつかの専門家は、これに光を当てて、私の心にこの毛羽をクリアしてください(例??)。 ので、私は、コールバック関数の使い方

またはそのための私の心は、単にあなたのコードにコールバック関数を配置/呼び出している場所の場所に依存させることができますか? 。

おかげで、

PS:(おそらくいくつかの例)私はこの質問は主観近いことだろうと怖いが、それでも私はこのための具体的な答えを期待できる

編集:実際にこれがあります私が不明瞭になり、インターネットからの例:

function do_a(){ 
    // simulate a time consuming function 
    setTimeout(function(){ 
    console.log('`do_a`: this takes longer than `do_b`'); 
    }, 1000); 
} 

function do_b(){ 
    console.log('`do_b`: this is supposed to come out after `do_a` but it comes out before `do_a`'); 
} 

do_a(); 
do_b(); 

結果

`do_b`: this is supposed to come out after `do_a` but it comes out before `do_a` 
`do_a`: this takes longer than `do_b` 

JSがシーケンシャルな場合、do_bは常に私の理解に従ってdo_aの後に来るべきです。

+6

JavaScriptは、JavaScriptのです。コンテキスト、使用法、エンジンなどに依存しています –

+0

ブロックされていないブロックとブロックされていないブロックがあるかどうか不明なサンプルコードを提供できますか? – Matt

+0

JavaScriptは一般的に同期ですが、setTimeoutは定義上は非同期です。ここには良い入門書があります:https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout –

答えて

2

長時間実行されているノードでは、関数/コールバックをキューに入れるのにprocess.nextTick()を使用します。これは、通常、ノードのAPIで行われ、長期間実行されているブロックやコードを使用して(api外で)プログラミングしない限り、実際にはあまり効果がありません。下のリンクはそれをよりよく説明しなければなりません。

howtonode process.nextTick()

jQueryのAJAXはまた、コールバックを取り、それがそのコード化されたようなコードの次のブロックに移動する前に、サーバーの応答を待つことはありません。サーバーが応答したときに実行される関数を記憶します。これは、ブラウザが公開するXMLHTTPRequestオブジェクトに基づいています。 XHRオブジェクトは、応答が返ったときにコールバックする関数を覚えています。

setTimeout(fn, 0)は、コールスタックが空(次に利用可能なフリーティック)で、非同期のような機能を作成するために使用できる機能を実行します。 setTimeout(fn, 0) question on stackoverflow

JavaScriptを非同期化するには、javascript自体と同じようにプログラムする必要があります。あなたはいくつかのAPI /スクリプトを使用していない限り、たくさんの関数呼び出しとコールバックを使うだけで魔法を得ることはできません。

Jquery Deferred Object jQueryの非同期機能のもう一つの良いリンクです。グーグルでは、jQuery Deferredがより多くの洞察のためにどのように機能するかについての情報を得ることができます。

22

JavaScriptのコアはほぼ同期しているため、完了する前にタスクが完全に完了しています。 AJAXが登場する以前は、実際には非同期動作を提供するのはsetTimeoutとsetIntervalのみでした。

しかし、イベントハンドラが事実上非同期コードであることは忘れやすいです。ハンドラをアタッチしてもハンドラコードは呼び出されず、そのコードは未知の時間まで実行されません。

その後、AJAXがサーバに呼び出されてきました。これらの呼び出しは同期するように構成することもできますが、開発者は一般に非同期呼び出しを使用し、それらを実装するためにコールバックメソッドを使用します。

次に、JSライブラリとツールキットの普及を見ました。これらは、さまざまなブラウザの実装を均質化するのに尽力し、非同期コードへのコールバックアプローチを基に構築されました。また、配列の繰り返しやCSSのクエリ結果の処理などのために、より多くの同期コールバックが表示されるようになりました。

今、私たちはミックスの中でDeferreds and Promisesを見ています。これらは長時間実行される操作の値を表すオブジェクトで、到着時にその値を処理するためのAPIを提供します。

NodeJSは、多くのことに対して非同期のアプローチに傾いています。それは多くの事実です。しかし、これはJSの本質的な非同期性の性質ではなく、設計上の決定です。

10

JavaScriptは常に同期(ブロッキング)シングルスレッド言語ですが、Javascriptはプログラミングを通じて非同期に動作させることができます。

同期コード:

console.log('a'); 
console.log('b'); 

非同期コード:

console.log('a'); 
setTimeout(function() { 
    console.log('b'); 
}, 1000); 
setTimeout(function() { 
    console.log('c'); 
}, 1000); 
setTimeout(function() { 
    console.log('d'); 
}, 1000); 
console.log('e'); 

この出力:E BはCのD

+0

この文脈ではブロックはどういう意味ですか? –

関連する問題