LoginSignup
8
4

More than 5 years have passed since last update.

Node.jsのSyncは出来る限り使うな!

Last updated at Posted at 2018-05-05

はじめに

ノンブロッキングIOをちゃんと理解していないのであれば、Node.jsにあるSyncと付く関数は出来る限り使わない方が良いです。

もちろん、用意されているからには、何かしら有用性はあるため、ちゃんと理解しているのであれば、ガンガン使って良いと思います。

なぜ使ってはいけないか

JavaScriptはシングルスレッドで動作します。なので、一つずつしか処理は出来ず、同時に複数の処理が実行されることはありません。

Node.jsのfs.readFileSyncのように、「~Sysnc」となっている関数は、同期処理であり、ブロッキングIOです。そのため、fs.readFileSyncでファイルをディスクから読み取っている間もCPUを占有し、他の処理を実行することが出来ません。

ExpressなどのWebアプリケーションは、複数のリクエストを同時に扱う必要があります。なので、fs.readFileSyncでファイルを読み込んでいる間に、他のリクエストが待たされることになります。これがブロッキングIOです。

しかし、fs.readFileという「~Sync」が付いていない関数であれば、ディスクからファイルを読み取っている間は、他のリクエストが処理を行うことが可能となります。これがノンブロッキングIOです。

Webアプリケーション以外(electronなど)であっても、複数処理を同時に実行する場合があるため、fs.readFileSyncではなくfs.readFileを使用した方がよいでしょう。

サンプル

以下は、ブロッキングIOです。

const express = require('express');
const router = express.Router();
const fs = require('fs');

router.get('/', function(req, res, next) {
  const content = fs.readFileSync('./test.txt', 'utf-8');
  res.json({
    result: content
  });
});

module.exports = router;

fs.readFileSyncでファイルを読み込んでいる間は、他の処理が待たされます。

以下は、ノンブロッキングIOです。

const express = require('express');
const router = express.Router();
const fs = require('fs');

router.get('/', function(req, res, next) {
  fs.readFile('./test.txt', 'utf-8', (err, content) => {
    res.json({
      result: content
    });
  });
});

module.exports = router;

fs.readFileでファイルを読み込んでいる間は、CPUを占有しないため、他の処理が実行可能となります。

最後に

fs.readFileSyncの方が読み込んだ内容が戻り値で取得できるため、コールバックで取得するfs.readFileと比べて簡単です。そのため、よくわかっていない人は、すぐにfs.readFileSyncを使ってしまいます。しかし、ブロッキングIOであるべき処理というのは、私の経験上あまり出会ったことはありません。(ブロッキングIOでも問題ない処理はあります。)なので、あくまでも私の考えですが、「~Sync」は使用しないで、できる限り「~Sync」が付いてない関数を使用した方がよいと思います。

8
4
1

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
8
4