サーバーサイドJavascriptエンジンのコンテキストでは、非ブロッキングI/Oまたは非同期I/Oとは何ですか?これは、サーバー側のJava実装よりも優れていると言われています。
同期実行は通常、順番に実行されるコードを指します。非同期実行とは、コードに表示される順序で実行されない実行のことです。次の例では、同期操作によりアラートが順番に発生します。非同期操作では、alert(2)
は2番目に実行されるように見えますが、実行されません。
同期:1,2,
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つのスレッドのみを使用してすべての要求を処理します。これは、Nodeのインスタンスが単一のスレッドを最大限に活用することを意味します。作成者は、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