web-dev-qa-db-ja.com

コールバックを使用すると、JavaScriptコードはどのように非同期になりますか?

私は、非同期JavaScriptコードの書き方を理解しようとして、オンラインで多くの読書をしてきました。私の研究で多く出てきたテクニックの1つは、コールバックを使用することです。コールバック関数を作成して実行する方法のプロセスは理解していますが、コールバックがJavaScriptの実行を自動的に非同期にするように見える理由がわかりません。だから、私の質問は:JavaScriptコードにコールバック関数を追加すると、コードが自動的に非同期になるのですか?

26
Zach Dziura

そうではありません。コールバックを受け取ったり、コールバックを渡したりしても、非同期であるとは限りません。

たとえば、.forEach関数はコールバックを受け取りますが、同期しています。

var available = false;
[1,2,3].forEach( function(){
    available = true;
});
//code here runs after the whole .forEach has run,
//so available === true here

setTimeoutもコールバックを受け取り、非同期です。

function myFunction( fn ) {
    setTimeout( function() {
        fn(1,2,3);
    }, 0 );
}

var available = false;
myFunction( function() {
    available = true;
});
//available is never true here

JavaScriptで非同期イベントにフックするには常にコールバックが必要ですが、関数の呼び出しやそれらの引き渡しが常に非同期であることを意味しません。

26
Esailija

「マジック」の秘密は、コールバックを割り当てるイベントが非同期であることです。 JSサンドボックス外のバックグラウンドで、リモートサーバーから何かを取得するなど、何をしているのかを処理するために、「内部」に実装されています。そして、作業が完了すると、JSエンジンにイベントを呼び出すためのメッセージを送信します。 JSエンジンが現在実行中の処理を完了すると、キューに入れられているすべてのイベントが呼び出され(または新しいメッセージを待機し)、コールバックが非同期で非同期に呼び出されます。

注:異なるJSエンジンが異なる方法で物事を実装するため、これは詳細には触れない非常に高レベルの概念的なトピックの概要です。しかし、これは一般的な考え方ですそれがどのように機能するか。)

23
Mason Wheeler