【保存版】Node.jsのchild_process.execとexecFileをPromise化:Bluebird、util.promisify、@escook/promise-ify徹底比較
Bluebird を使って Node.js の child_process.exec と child_process.execFile 関数をPromise化する方法
一方、Promiseは非同期処理をより扱いやすくするために広く使用されています。Bluebirdは、Promiseライブラリの中でも特に人気があり、多くの追加機能を提供します。
このチュートリアルでは、Bluebirdを使用して child_process.exec
と child_process.execFile
関数をPromise化する方法を説明します。
Bluebirdのインストール
まず、Bluebirdをプロジェクトにインストールする必要があります。
npm install bluebird
child_process.exec のPromise化
以下のコードは、child_process.exec
関数をPromise化する関数 execAsync
を定義します。
const Promise = require('bluebird');
const childProcess = require('child_process');
const execAsync = Promise.promisify(childProcess.exec);
execAsync('ls')
.then(stdout => console.log(stdout))
.catch(err => console.error(err));
このコードは、ls
コマンドを実行し、その出力をコンソールに出力します。
const execFileAsync = Promise.promisify(childProcess.execFile);
execFileAsync('node', ['-p', 'process.version'], { encoding: 'utf8' })
.then(stdout => console.log(stdout))
.catch(err => console.error(err));
このコードは、node
コマンドを実行し、Node.jsのバージョンを出力します。
利点
Promise化により、child_process
関数の非同期処理をより扱いやすくなります。コードがより読みやすく、メンテナンスしやすくなります。
注意点
Bluebirdは非推奨となり、現在はメンテナンスされていません。新しいプロジェクトでは、代わりに util.promisify
または @escook/promise-ify
などの代替手段を使用することを検討してください。
Bluebird を使って Node.js の child_process.exec と child_process.execFile 関数をPromise化する方法:サンプルコード
npm install bluebird
const Promise = require('bluebird');
const childProcess = require('child_process');
const execAsync = Promise.promisify(childProcess.exec);
(async () => {
try {
const stdout = await execAsync('ls');
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
const execFileAsync = Promise.promisify(childProcess.execFile);
(async () => {
try {
const stdout = await execFileAsync('node', ['-p', 'process.version'], { encoding: 'utf8' });
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
説明
Promise.promisify
関数は、非同期関数をPromiseベースの関数に変換するために使用されます。async
/await
キーワードは、Promiseベースのコードを記述するために使用されます。try
/catch
ブロックは、Promise操作中に発生する可能性のあるエラーを処理するために使用されます。
補足
- これらの例は、Bluebirdを使用して
child_process
関数をPromise化する方法を示す基本的な例です。 - より複雑なユースケースについては、Bluebirdと
child_process
モジュールのドキュメントを参照してください。
Bluebird 以外の child_process.exec と child_process.execFile 関数を Promise 化する方法
util.promisify を使用する
Node.js 10 以降では、組み込みの util.promisify
関数を使用して非同期関数を Promise 化することができます。
const { promisify } = require('util');
const childProcess = require('child_process');
const execAsync = promisify(childProcess.exec);
const execFileAsync = promisify(childProcess.execFile);
(async () => {
try {
const stdout = await execAsync('ls');
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
(async () => {
try {
const stdout = await execFileAsync('node', ['-p', 'process.version'], { encoding: 'utf8' });
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
この方法は、Bluebird をインストールする必要がなく、コードを簡潔に保つことができます。
@escook/promise-ify
は、Bluebird の代替となる軽量な Promise ライブラリです。
const promiseify = require('@escook/promise-ify');
const childProcess = require('child_process');
const execAsync = promiseify(childProcess.exec);
const execFileAsync = promiseify(childProcess.execFile);
(async () => {
try {
const stdout = await execAsync('ls');
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
(async () => {
try {
const stdout = await execFileAsync('node', ['-p', 'process.version'], { encoding: 'utf8' });
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
この方法は、Bluebird よりも軽量で、パフォーマンスが優れている可能性があります。
自作の Promise 化関数を作成する
より柔軟な制御が必要な場合は、独自の Promise 化関数を作成することができます。
const childProcess = require('child_process');
function execAsync(command) {
return new Promise((resolve, reject) => {
childProcess.exec(command, (err, stdout, stderr) => {
if (err) {
reject(err);
return;
}
resolve(stdout);
});
});
}
function execFileAsync(file, args, options) {
return new Promise((resolve, reject) => {
childProcess.execFile(file, args, options, (err, stdout, stderr) => {
if (err) {
reject(err);
return;
}
resolve(stdout);
});
});
}
(async () => {
try {
const stdout = await execAsync('ls');
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
(async () => {
try {
const stdout = await execFileAsync('node', ['-p', 'process.version'], { encoding: 'utf8' });
console.log(stdout);
} catch (err) {
console.error(err);
}
})();
この方法は、より詳細なエラー処理や、オプションの処理など、より多くの制御を提供します。
最適な方法の選択
使用する方法は、ニーズと好みによって異なります。
- 簡潔さ:
util.promisify
を使用すると、最も簡潔なコードになります。 - 柔軟性: 自作の Promise 化関数を使用すると、より多くの制御とオプションを提供できます。
Bluebird の非推奨について
javascript node.js promise