14
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Node.jsで書く時に気をつけたいこと

Posted at

Node.jsはサーバサイドJavaScript実行環境です。
このNode.jsの最大な特徴が ノンブロッキングI/O です。

いままでサーバサイドで動く物となるとshellやperl,rubyなどがありましたがノンブロッキングI/Oではありません。

ノンブロッキングI/Oについて

すごーく簡単な例えを言うと ワンオペを効率良くこなす 感じ。
従来のプログラミングでは料理を火にかけてる間完成するまでその場から離れません。
火にかけて、出来上がる間に他の下準備をできる。それがノンブロッキングI/Oです!

あ、具体例がないのでわからない?なるほど。

ファイルを開いて読む/書く、DBに問い合わせるなどの処理が従来であれば結果を返すまで処理を待つのがブロッキングI/Oです。
ノンブロッキングI/Oでは結果を待たずして次の処理へ行きます。

このノンブロッキングI/Oの特徴から処理の順番を制御しようとするとコールバック地獄に陥ったりします。
いま現在、順番制御しようとするとAsyncモジュールを使うのが一般的ですかね。

if...elseをしっかり書こう

やっとこ本題

db.js
db.find(sql, function(err, docs){
  if(err) return errToNext(err);
  docs.forEach(...);
})

例としてこんな書き方をすることがある。
errがあればerrToNext関数の返り値をリターンする。
errがなければ次のdocs.forEachを実行する形になる。

だが、ちょっと待ってほしい。
もしもerrToNext関数内部にブロッキングI/Oを発生させる処理があったら?

returnが返らないで次の処理へ行ってしまい本物のExceptionが発生するので

db.js
db.find(sql, function(err, docs){
  if(err){
    return errToNext(err);
  }else{
    docs.forEach(...);
  }
})

ノンブロッキングI/Oでは面倒臭がらずキチンと書きましょう。

おわりに

今回の件は実際にハマったことを書いてみました。
どんな関数でも呼ぶと順番が保証できない可能性が高いので条件分岐はきっちり書こうという教訓でした。

14
17
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?