How to wait for a child process to finish in Node.js

node.jsChild Process

node.js Problem Overview


I'm running a Python script through a child process in Node.js, like this:

require('child_process').exec('python celulas.py', function (error, stdout, stderr) {
	child.stdout.pipe(process.stdout);
});

but Node doesn't wait for it to finish. How can I wait for the process to finish?

Is it possible to do this by running the child process in a module I call from the main script?

node.js Solutions


Solution 1 - node.js

Use exit event for the child process.

var child = require('child_process').exec('python celulas.py')
child.stdout.pipe(process.stdout)
child.on('exit', function() {
  process.exit()
})

PS: It's not really a duplicate, since you don't want to use sync code unless you really really need it.

Solution 2 - node.js

NodeJS supports doing this synchronously.
Use this:

const execSync = require("child_process").execSync;
    
const result = execSync("python celulas.py");
    
// convert and show the output.
console.log(result.toString("utf8"));

Remember to convert the buffer into a string. Otherwise you'll just be left with hex code.

Solution 3 - node.js

A simple way to wait the end of a process in nodejs is :

const child = require('child_process').exec('python celulas.py')

await new Promise( (resolve) => {
    child.on('close', resolve)
})

Solution 4 - node.js

In my opinion, the best way to handle this is by implementing an event emitter. When the first spawn finishes, emit an event that indicates that it is complete.

const { spawn } = require('child_process');
const events = require('events');
const myEmitter = new events.EventEmitter();


firstSpawn = spawn('echo', ['hello']);
firstSpawn.on('exit', (exitCode) => {
    if (parseInt(exitCode) !== 0) {
        //Handle non-zero exit
    }
    myEmitter.emit('firstSpawn-finished');
}

myEmitter.on('firstSpawn-finished', () => {
    secondSpawn = spawn('echo', ['BYE!'])
})

Solution 5 - node.js

You should use exec-sync

That allow your script to wait that you exec is done

really easy to use:

var execSync = require('exec-sync');

var user = execSync('python celulas.py');

Take a look at: https://www.npmjs.org/package/exec-sync

Solution 6 - node.js

You need to remove the listeners exec installs to add to the buffered stdout and stderr, even if you pass no callback it still buffers the output. Node will still exit the child process in the buffer is exceeded in this case.

var child = require('child_process').exec('python celulas.py');
child.stdout.removeAllListeners("data");
child.stderr.removeAllListeners("data");
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

Solution 7 - node.js

You can make use of Util.promisify, e.g.:

const { exec } = require('child_process');
const Util = require('util');
const asyncExec = Util.promisify(exec);

asyncExec('python celulas.py')
.then((stdout, stderr) => {
    stdout.pipe(process.stdout);
    })
.catch(error => {
    console.log('error : ', error);
 });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDavidView Question on Stackoverflow
Solution 1 - node.jsalexView Answer on Stackoverflow
Solution 2 - node.jsAndrija JostergårdView Answer on Stackoverflow
Solution 3 - node.jsFrédéric PluquetView Answer on Stackoverflow
Solution 4 - node.jsTylersSNView Answer on Stackoverflow
Solution 5 - node.jsFrederic NaultView Answer on Stackoverflow
Solution 6 - node.jsKristofor SeldenView Answer on Stackoverflow
Solution 7 - node.jsNNHView Answer on Stackoverflow