Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

1.1K
Vistas
How to promisify Node's child_process.exec and child_process.execFile functions with Bluebird?

I'm using the Bluebird promise library under Node.js, it's great! But I have a question:

If you take a look at the documentation of Node's child_process.exec and child_process.execFile you can see that both of these functions are returning a ChildProcess object.

So what's the recommended way to promisify such functions?

Note that the following works (I get a Promise object):

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

But how can one get access to the original return value of the original Node.js functions? (In these cases I would need to be able to access the originally returned ChildProcess objects.)

Any suggestion would be appreciated!

EDIT:

Here is an example code which is using the return value of the child_process.exec function:

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

But if I would use the promisified version of the exec function ( execAsync from above ) then the return value will be a promise, not a ChildProcess object. This is the real problem I am talking about.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

I would recommend using standard JS promises built into the language over an additional library dependency like Bluebird.

If you're using Node 10+, the Node.js docs recommend using util.promisify which returns a Promise<{ stdout, stderr }> object. See an example below:

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

Handle errors first from stderr.

over 4 years ago · Santiago Trujillo Denunciar

0

It sounds like you'd like to return two things from the call:

  • the ChildProcess
  • a promise that resolves when the ChildProcess completes

So "the recommended way to promisify such functions"? Don't.

You're outside the convention. Promise returning functions are expected to return a promise, and that's it. You could return an object with two members (the ChildProcess & the promise), but that'll just confuse people.

I'd suggest calling the unpromisified function, and creating a promise based off the returned childProcess. (Maybe wrap that into a helper function)

This way, it's quite explicit for the next person who reads the code.

Something like:

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

If you're just wanting to promisify specifically child_process.exec() and child_process.execFile(), in recent node versions there is a better answer here.

over 4 years ago · Santiago Trujillo Denunciar

0

Since Node v12 the built-in util.promisify allows access to the ChildProcess object in the returned Promise for built-in functions where it would have been returned by the un-promisified call. From the docs:

The returned ChildProcess instance is attached to the Promise as a child property.

This correctly and simply satisfies the need to access ChildProcess in the original question and makes other answers out of date providing that Node v12+ can be used.

Adapting the example (and concise style) provided by the questioner, access to the ChildProcess can be achieved like:

const util = require('util');
const exec = util.promisify(require('child_process').exec);
const promise = exec('node ./commands/server.js');
const child = promise.child; 

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

// i.e. can then await for promisified exec call to complete
const { stdout, stderr } = await promise;
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda