如何将 promisify() 与 spawn() 函数一起用于“child_process”?

问题描述 投票:0回答:3

我有以下代码示例,我现在知道如何仅使用

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();
node.js child-process spawn
3个回答
5
投票

我无法快速找出为什么

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);
  }
})();



2
投票

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);
            });
}

1
投票

这是不可能的,因为没有什么可以

promisify
promisify
适用于需要回调的函数,而
spawn
不需要回调。

您可以通过获取返回的

spawn
然后将侦听器添加到
ChildProcess
' 可读流(
ChildProcess
stdout
stderr
...)来使用
stdio

Omar Omeiri 的答案类似于

execFile
如何在节点本身内部工作,因此您可以使用承诺的
execFile
来代替。 (如果需要无限缓冲,请在选项中传入
maxBuffer: Infinity

© www.soinside.com 2019 - 2024. All rights reserved.