如何使用Bluebird来规范Node的child_process.exec和child_process.execFile函数?

2022-08-30 04:03:34

我正在使用Node下的Bluebird promise库.js,这太棒了!但我有一个问题:

如果您查看Node的child_process.execchild_process.execFile的文档,您可以看到这两个函数都返回ChildProcess对象。

那么,推荐的实现此类功能的方法是什么呢?

请注意,以下工作(我得到一个Promise对象):

var Promise = require('bluebird');
var execAsync = Promise.promisify(require('child_process').exec);
var execFileAsync = Promise.promisify(require('child_process').execFile);

但是,如何才能访问原始 Node 的原始返回值.js函数呢?(在这些情况下,我需要能够访问最初返回的 ChildProcess 对象。

任何建议将不胜感激!

编辑:

下面是一个使用 child_process.exec 函数的返回值的示例代码:

var exec = require('child_process').exec;
var child = exec('node ./commands/server.js');
child.stdout.on('data', function(data) {
    console.log('stdout: ' + data);
});
child.stderr.on('data', function(data) {
    console.log('stderr: ' + data);
});
child.on('close', function(code) {
    console.log('closing code: ' + code);
});

但是,如果我使用exec函数的promisized版本(上面的execAsync),那么返回值将是一个承诺,而不是一个ChildProcess对象。这就是我所说的真正问题。


答案 1

我建议使用内置于语言中的标准JS承诺,而不是像Bluebird这样的其他库依赖项。

如果您使用的是 Node 10+,则 Node.js 文档建议使用 哪个返回对象。请参阅下面的示例:util.promisifyPromise<{ stdout, stderr }>

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

async function lsExample() {
  try {
    const { stdout, stderr } = await exec('ls');
    console.log('stdout:', stdout);
    console.log('stderr:', stderr);
  } catch (e) {
    console.error(e); // should contain code (exit code) and signal (that caused the termination).
  }
}
lsExample()

首先从 中处理错误。stderr


答案 2

听起来您希望从呼叫中返回两件事:

  • 子进程
  • 在子进程完成时解决的承诺

那么“推荐的实现这些功能的方式”呢?不要

你置身于惯例之外。承诺返回函数应该返回一个承诺,仅此而已。您可以返回一个具有两个成员(ChildProcess和promise)的对象,但这只会使人们感到困惑。

我建议调用未承诺的函数,并根据返回的子进程创建一个承诺。(也许可以将其包装到帮助器函数中)

这样,对于下一个阅读代码的人来说,这是非常明确的。

像这样:

var Promise = require('bluebird');
var exec = require('child_process').execFile;

function promiseFromChildProcess(child) {
    return new Promise(function (resolve, reject) {
        child.addListener("error", reject);
        child.addListener("exit", resolve);
    });
}

var child = exec('ls');

promiseFromChildProcess(child).then(function (result) {
    console.log('promise complete: ' + result);
}, function (err) {
    console.log('promise rejected: ' + err);
});

child.stdout.on('data', function (data) {
    console.log('stdout: ' + data);
});
child.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
});
child.on('close', function (code) {
    console.log('closing code: ' + code);
});

如果你只是想专门提出和,在最近的节点版本中,这里有一个更好的答案。child_process.exec()child_process.execFile()