Node.jsがとっつきにくいと思ったら ~非同期処理とは?~【初心者向け】


背景

JavaやらPythonやらの言語でエンジニア人生を送っていると、Node.jsでバックエンド処理を作っていると「何か違う~!!」と感じたのでこの記事を書いていく
なお、node.jsはjavascriptをサーバーサイドでも動かせるようにした実行環境や処理系のことを指す。

Node.jsってどんな言語?

Node.jsは他の言語と比べて決定的に異なる点がある。「ノンブロッキングI/O」という処理方式を採用している点だ。ブロッキングとは、Node.jsのプログラムを実行する際に、ファイル呼び出しやネットワークリクエストなどNode.js以外の操作が完了するまで待たなければならない状態だ。ブロッキングが発生すると、プログラムの次の処理に進むことができない。Node.jsでは、このブロッキングを避けるため「ノンブロッキングI/O」という非同期処理を採用している。ファイル呼び出しやネットワークリクエストの処理の結果を待たずに次のプログラムコードが実行される。

const fs = require('fs'); // ファイル読込ライブラリ

// ファイル内容をコンソールに出力するコールバック関数
const fileoutput = (err, txt) => {
  console.log(txt); 
};

console.log('前');
fs.readFile('./readme.txt', 'utf8', fileoutput);
console.log('後');

上記のプログラムを実行すると、前、後、ファイルの中身という順番でコンソールに出力される。ファイル読込の処理結果を待たず、次のプログラムコードが実行されていることが分かるだろう。

なぜ非同期?

非同期的にプログラムを実行して、ブロッキングをなぜ避けなければいけないのかというと、Node.jsはシングルスレッドで動く処理だからだ。スレッドとは、プログラムを実行する実行単位のことだ。例えばWebサーバーにリクエストがきて、プログラムを実行する際に並列で実行できないとすると、シングルスレッドのためプログラムを実行する場所が他になく、大幅に処理が滞ってしまう。そのため、非同期で次の処理を実行できるようにしているのだ。そのため、メモリを効率的に利用できたり、プロセスのデッドロックが起こりにくいというメリットがある。

まとめ

Node.jsのほとんどの関数はこのように非同期で実施されるため、実行される順番には留意してコードを書こう