代码之家  ›  专栏  ›  技术社区  ›  Michael Jay

如何使用节点的child\u进程。exec()承诺

  •  3
  • Michael Jay  · 技术社区  · 8 年前

    我尝试使用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 回复  |  直到 8 年前
        1
  •  12
  •   matteocng Wes    6 年前

    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, reject) => {
            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, reject) => {
        try {
            resolve(childProcess.execSync(command));
        } catch(error) {
          reject(error) 
        }
    });
    
        2
  •  1
  •   bloo    5 年前

    我知道这是一个老问题,但这里有一个有用的工具,我发现与节点前一段时间。。。假设您有一个节点文件 app.ts ,在typescript中,即。。。

    应用程序。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中,可能是这样的

    应用程序。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();