如何将节点的child_process.exec()与promises

时间:2018-05-14 14:20:13

标签: node.js exec child-process

我尝试使用node.js(docker exec命令)顺序执行长进程。

我做:

const childProcess = require('child_process');

const execWithPromise = async command => {
    return new Promise(async resolve => {
        const process = childProcess.exec(command);

        process.on('exit', err => resolve(err));
        process.on('close', err => resolve(err));
    });
};

const run = async () => {
    await execWithPromise('/usr/local/bin/docker exec -i -t cucumber node long-running-script.js');
    await execWithPromise('/usr/local/bin/docker exec -i -t cucumber node long-running-script.js');
};

run();

但承诺立即得到解决,结果为1.在这两种情况下。该命令在命令行上运行就好了。

为什么会立即返回?

2 个答案:

答案 0 :(得分:2)

child_process.exec期望将回调作为第二个或第三个参数。它没有回复承诺。根据您的用例和节点版本,您有几个选择。

使用回调并返回解决方案。

return new Promise(async resolve => {
     childProcess.exec(command, (err, stout, sterr) {
        resolve(err ? stout : sterr)
      }
  });

使用spawn代替(保留大部分代码)

const execWithPromise = async command => {
    return new Promise(async resolve => {
        const process = childProcess.spawn(command);
        process.on('data', data => resolve(data));
        process.on('error', err => reject(err));
        process.on('close', err => reject(err));
    });
};

将execSync与try catch

一起使用
return new Promise(async resolve => {
    try {
        resolve(childProcess.execSync(command));
    } catch(error) {
      reject(error) 
    }
});

答案 1 :(得分:0)

我知道这是一个老问题,但是这是我不久前在node上发现的一个有用的工具...所以,假设您有一个节点文件app.ts,它的打字稿是...

app.ts

import utils from 'util'; // The thing that is useful, it has a bunch of useful functions
import { exec } from 'child_process'; // The exec import

export function execute(command: string): Promise<any> {
    // Not too concerned about the return type here
    return utils.promisify(exec)(command);
}

const run = async () => {
    await execute('/usr/local/bin/docker exec -i -t cucumber node long-running-script.js');
    await execute('/usr/local/bin/docker exec -i -t cucumber node long-running-script.js');
};

run();

尽管在js中可能是这样的

app.js

const utils = require('util');
const exec = require('child_process').exec;

function execute(command) {
    return utils.promisify(exec)(command);
}

const run = async () => {
    await execute('/usr/local/bin/docker exec -i -t cucumber node long-running-script.js');
    await execute('/usr/local/bin/docker exec -i -t cucumber node long-running-script.js');
};

run();