回答:
同期実行とは通常、コードが順番に実行されることを指します。非同期実行とは、コードに表示されるシーケンスで実行されない実行を指します。次の例では、同期操作によりアラートが順番に発生します。非同期操作では、alert(2)
2番目に実行されているように見えますが、実行されていません。
同期:1、2、3
alert(1);
alert(2);
alert(3);
非同期:1,3,2
alert(1);
setTimeout(() => alert(2), 0);
alert(3);
ブロッキングとは、その操作が完了するまで、以降の実行をブロックする操作を指します。非ブロッキングとは、実行をブロックしないコードを指します。与えられた例でlocalStorage
は、は実行を停止して読み取りをブロックする操作です。一方、fetch
はalert(3)
実行から停止しないため、非ブロッキング操作です。
// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);
// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);
非ブロッキングの非同期操作の利点の1つは、単一のCPUとメモリの使用を最大化できることです。
同期ブロッキング操作の例は、JavaまたはPHPのような一部のWebサーバーがIOまたはネットワーク要求を処理する方法です。コードがファイルまたはデータベースから読み取る場合、コードは実行後のすべてを「ブロック」します。その期間、マシンはメモリを保持し、何も実行していないスレッドの処理時間を保持します。
そのスレッドが停止している間に他の要求に応えるために、ソフトウェアに依存します。ほとんどのサーバーソフトウェアは、追加の要求に応えるために、より多くのスレッドを生成します。これには、より多くのメモリが消費され、より多くの処理が必要になります。
Nodeで作成されたような非同期の非ブロッキングサーバーは、1つのスレッドのみを使用してすべての要求を処理します。これは、ノードのインスタンスがシングルスレッドを最大限に活用することを意味します。作成者は、I / Oとネットワーク操作がボトルネックであることを前提に設計しました。
リクエストがサーバーに到着すると、1つずつ処理されます。ただし、サービスされるコードがDBにクエリを実行する必要がある場合などは、コールバックを2番目のキューに送信し、メインスレッドは実行を継続します(待機しません)。DB操作が完了して戻ると、対応するコールバックが2番目のキューから取り出され、3番目のキューに入れられ、そこで実行が保留されます。エンジンが他の何かを実行する機会を得たとき(実行スタックが空になったときなど)、エンジンは3番目のキューからコールバックを取得して実行します。
var startTime = new Date().getTime();
var getEndTime = () => {
var tempEndTime = new Date().getTime();
var second = (tempEndTime - startTime)/1000
return `took ${second} sec...to finish\n`
}
console.log('1: start App', getEndTime())
setTimeout(()=>{
console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())
// console -> Process Order: 1 -> 3 -> 2