JavaScriptは基本的にシングルスレッドで動いています。
これはつまり、JavaScriptは並行処理はできないということです。
同期であろうと非同期であろうと2つ以上の処理を同時に行なうことはできません。
JavaScriptでは、キューに登録された関数が順番にひとつずつ実行されていきます。
そしてJavaScriptのもうひとつの特徴として、JavaScriptは非同期処理できることです。
非同期処理とは、例えばデータベースに仕事を任せている間に自分の他の仕事を進めることができることです。
同期処理の例
1 2 3 | console.log(1); console.log(2); console.log(3); |
結果は1 2 3の順番で表示されます。
コンソールログの値が上から順番に実行されて表示されました。
非同期処理の例
1 2 3 | console.log(1); setTimeout(() => {console.log(2)}, 1000); console.log(3); |
結果は1 3 2の順番に表示されます。
console.log(1)の実行後、次にconsole.log(2)がタイマーに登録され、console.log(3)が実行されます。これは同期処理ですが、タイマーがカウントする間をconsole.log(3)は待たずに実行されます。この処理が非同期処理になります。
console.log(2)の処理では、関数setTimeoutに無名関数() => {console.log(2)}を渡しています。このように、ある関数Aの引数に別の関数Bを渡し、AからBを呼び出すことをコールバックといいます。
コールバック地獄の例
次のサンプルはコールバック地獄と呼ばれるものです。
何層にもコールバックを行うことで、コードの可読性が悪くなりメンテナンス性も悪くなってしまいます。
コールバック地獄の例
1 2 3 4 5 6 7 8 9 10 11 12 | setTimeout(() => { console.log( "done1" ); setTimeout(() => { console.log( "done2" ); setTimeout(() => { console.log( "done3" ); setTimeout(() => { console.log( "done4" ); }, 1000); }, 1000); }, 1000); }, 1000); |
このように何層もコールバックをするのは避けたいところです。そしてその対策として使われるのがPromiseになります。
Promiseについては別途説明します。