情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsでプログラムの終了直前に処理を行う

プログラムの終了直前に処理を行うにはprocessオブジェクトのexitイベントにイベントハンドラを登録します。

このイベントハンドラの第1引数はリターンコードです。

これにより、プログラムの終了直前にこのイベントハンドラが呼び出されるようになります。

ただし、このイベントハンドラが呼び出される時点ではもうイベントループを使用することはできなくなっています

そのため、非同期的な処理は一切行うことができませんので注意してください。

つまり、このイベントハンドラでは同期的な処理しか行うことができません


プログラムの終了直前に非同期的な処理を行うにはprocessオブジェクトのbeforeExitイベントにイベントハンドラを登録します。

これにより、プログラムの終了直前にこのイベントハンドラが呼び出されるようになります。

ただし、このイベントハンドラはプログラムが自然に終了しようとしている場合にしか呼び出されません。process.exit関数でプログラムを終了しようとした場合や未処理の例外によりプログラムが異常終了しようとしている場合には呼び出されませんので注意してください。

また、このイベントハンドラで非同期的な処理が行われた場合、処理が完了し、プログラムが終了する直前には再びこのイベントハンドラが呼び出されることに注意してください。特に無限ループとならないように細心の注意が必要です。


なお、processオブジェクトのexitイベントとbeforeExitイベントの両方にイベントハンドラが登録されている場合にはbeforeExitイベントのイベントハンドラの方が先に呼び出されます。

サンプルコード1

プログラムが自然に終了する場合の例です。

process-on-exit-1.js

process.on('exit', function (code) {
    console.log('exiting program...');
    console.log('return code: ' + code);
});

console.log('this is program 1.');

実行結果

C:\work\node>node process-on-exit-1.js
this is program 1.
exiting program...
return code: 0

サンプルコード2

process.exit関数でプログラムを終了する場合の例です。

process-on-exit-2.js

process.on('exit', function (code) {
    console.log('exiting program...');
    console.log('return code: ' + code);
});

console.log('this is program 2.');

process.exit(1);

実行結果

C:\work\node>node process-on-exit-2.js
this is program 2.
exiting program...
return code: 1

サンプルコード3

exitイベントのイベントハンドラで非同期的な処理を行おうとする例です(これは悪い例です。このようなコードは書かないようにしてください)。

process-on-exit-3.js

var fs = require('fs');

process.on('exit', function (code) {
    console.log('exiting program...');
    console.log('return code: ' + code);

    fs.readFile('process-on-exit-3.js', 'utf-8', function (err, data) {
        if (err) {
            console.error(err);
            process.exit(1);
        }
        else {
            console.log(data);
        }
    });
});

console.log('this is program 3.');

実行結果

非同期的な処理は行われていないことが分かります。

C:\work\node>node process-on-exit-3.js
this is program 3.
exiting program...
return code: 0

サンプルコード4

未処理の例外によりプログラムが異常終了する場合の例です。

process-on-exit-4.js

process.on('exit', function (code) {
    console.log('exiting program...');
    console.log('return code: ' + code);
});

console.log('this is program 4.');

throw new Error('error');

実行結果

C:\work\node>node process-on-exit-4.js
this is program 4.
exiting program...
return code: 1
C:\work\node\process-on-exit-4.js:8
throw new Error('error');
^

Error: error
    at Object.<anonymous> (C:\work\node\process-on-exit-4.js:8:7)
    at Module._compile (module.js:397:26)
    at Object.Module._extensions..js (module.js:404:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:429:10)
    at startup (node.js:139:18)
    at node.js:999:3

サンプルコード5

プログラムが自然に終了する場合の例です。

process-on-before-exit-1.js

process.on('beforeExit', function () {
    console.log('exiting program...');
});

console.log('this is program 5.');

実行結果

C:\work\node>node process-on-before-exit-1.js
this is program 5.
exiting program...

サンプルコード6

process.exit関数でプログラムを終了する場合の例です。

process-on-before-exit-2.js

process.on('beforeExit', function () {
    console.log('exiting program...');
});

console.log('this is program 6.');

process.exit(1);

実行結果

イベントハンドラが呼び出されていないことが分かります。

C:\work\node>node process-on-before-exit-2.js
this is program 6.

サンプルコード7

beforeExitイベントのイベントハンドラで非同期的な処理を行う例です。

process-on-before-exit-3.js

var fs = require('fs');

process.once('beforeExit', function () {
    console.log('exiting program...');

    fs.readFile('process-on-before-exit-3.js', 'utf-8', function (err, data) {
        if (err) {
            console.error(err);
            process.exit(1);
        }
        else {
            console.log(data);
        }
    });
});

console.log('this is program 7.');

実行結果

非同期的な処理が行われていることが分かります。

C:\work\node>node process-on-before-exit-3.js
this is program 7.
exiting program...
var fs = require('fs');

process.once('beforeExit', function () {
        console.log('exiting program...');

        fs.readFile('process-on-before-exit-3.js', 'utf-8', function (err, data) {
                if (err) {
                        console.error(err);
                        process.exit(1);
                }
                else {
                        console.log(data);
                }
        });
});

console.log('this is program 7.');

サンプルコード8

未処理の例外によりプログラムが異常終了する場合の例です。

process-on-before-exit-4.js

process.on('beforeExit', function () {
    console.log('exiting program...');
});

console.log('this is program 8.');

throw new Error('error');

実行結果

イベントハンドラが呼び出されていないことが分かります。

C:\work\node>node process-on-before-exit-4.js
this is program 8.
C:\work\node\process-on-before-exit-4.js:7
throw new Error('error');
^

Error: error
    at Object.<anonymous> (C:\work\node\process-on-before-exit-4.js:7:7)
    at Module._compile (module.js:397:26)
    at Object.Module._extensions..js (module.js:404:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:429:10)
    at startup (node.js:139:18)
    at node.js:999:3

サンプルコード9

exitイベントとbeforeExitイベントの両方にイベントハンドラを登録する例です。

process-on-before-exit.js

var i = 0;
process.on('beforeExit', function () {
    i++;
    if (i === 5) {
        process.removeAllListeners('beforeExit');
    }
    setTimeout(function () {
        console.log('i = ' + i);
    }, 1);
});
process.on('exit', function (code) {
    console.log('exiting program...');
    console.log('return code: ' + code);
});

console.log('this is program 9.');

実行結果

C:\work\node>node process-on-before-exit.js
this is program 9.
i = 1
i = 2
i = 3
i = 4
i = 5
exiting program...
return code: 0

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js