我有以下代码示例,我现在知道如何仅使用
utils.promisify();
解决此问题!不承诺!
const spawn = child_process.spawn('docker', ['--version']);
spawn.stdout.on('data', (data) => {
process.stdout.write(data);
});
spawn.on('error', () => {
process.stderr.write(error);
process.exit(1);
});
第二个代码示例运行良好。
const promisifiedExecFile = promisify(child_process.execFile);
async function test() {
const version = await promisifiedExecFile('docker', ['--version']);
console.log(version);
}
test();
我无法快速找出为什么
promisify
功能不能与 spawn
功能正常工作。但是你可以像这样创建自己的 promisify 函数:
TS
import { spawn as spwn } from 'child_process';
const spawn = (
cmd: string,
args: ReadonlyArray<string>,
) => new Promise((resolve, reject) => {
const cp = spwn(cmd, args);
const error: string[] = [];
const stdout: string[] = [];
cp.stdout.on('data', (data) => {
stdout.push(data.toString());
});
cp.on('error', (e) => {
error.push(e.toString());
});
cp.on('close', () => {
if (error.length) reject(error.join(''));
else resolve(stdout.join(''));
});
});
(async () => {
try {
const stdOut = await spawn('docker', ['--version']);
console.log('stdOut: ', stdOut);
} catch (error) {
console.log('error:', error);
process.exit(1);
}
})();
JS
const { spawn: spwn } = require('child_process');
const spawn = (
cmd,
args,
) => new Promise((resolve, reject) => {
const cp = spwn(cmd, args);
const error = [];
const stdout = [];
cp.stdout.on('data', (data) => {
stdout.push(data.toString());
});
cp.on('error', (e) => {
error.push(e.toString());
});
cp.on('close', () => {
if (error.length) reject(error.join(''));
else resolve(stdout.join(''));
});
});
(async () => {
try {
const stdOut = await spawn('docker', ['--version']);
console.log('stdOut: ', stdOut);
} catch (error) {
console.log('error: ', error);
process.exit(1);
}
})();
Node.js 的内置 util 包有一个
promisify()
函数,可以将基于回调的函数转换为基于 Promise 的函数。这使您可以将 Promise 链和异步/等待与基于回调的 API 结合使用。
我认为我们不能将
promisify()
与 spawn()
函数一起使用。
例如,我们可以将 promisify()
与 execFile()
一起使用,而不是 spawn()
:
async asyncExecFile(tool) {
const execFile = util.promisify(child_process.execFile);
return await execFile(tool, ['--version'])
.catch(() => {
this.printError(`The "${tool}" don't exist in the current environment. \n`);
process.exit(0);
});
}
这是不可能的,因为没有什么可以
promisify
。 promisify
适用于需要回调的函数,而 spawn
不需要回调。
您可以通过获取返回的
spawn
然后将侦听器添加到 ChildProcess
' 可读流(ChildProcess
、stdout
、stderr
...)来使用 stdio
execFile
如何在节点本身内部工作,因此您可以使用承诺的 execFile
来代替。 (如果需要无限缓冲,请在选项中传入maxBuffer: Infinity
)