如何使用 Bluebird 承诺 Node 的 child_process.exec 和 child_process.execFile 函数?

新手上路,请多包涵

我在 Node.js 下使用 Bluebird promise 库,它很棒!但我有一个问题:

如果您查看 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 函数的 promisified 版本(上面的 execAsync ),那么返回值将是一个 promise,而不是 ChildProcess 对象。这才是我说的真正的问题。

原文由 Zoltan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 351
2 个回答

听起来您想从通话中返回两件事:

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

那么“承诺此类功能的推荐方式”? 不要

你在公约之外。 Promise 返回函数应该返回一个 promise,仅此而已。您可以返回一个包含两个成员(ChildProcess 和 promise)的对象,但这只会让人感到困惑。

我建议调用 unpromisified 函数,并根据返回的 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() ,在最近的节点版本中, 这里 有更好的答案。

原文由 Ivan Hamilton 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

如果您使用的是 Node 10+, Node.js 文档 建议使用 util.promisify 返回一个 Promise<{ 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 处理错误。

原文由 shmck 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题