I'm trying to write a little module that uses child_process.spawn
to clone a git repo and return a Promise but it fails on me. When I'm using spawnSync it works.
Here is the sync code that works.
import {spawnSync} from 'child_process';
export default async function clone(options: { url: string; path: string; }) {
const url = options.url;
const target = options.path;
const args = ['clone', url, target];
return spawnSync('git', args);
}
This is the async code that fails and returns undefined
import {spawn} from 'child_process';
export default async function clone(options: { url: string; path: string; }) {
const url = options.url;
const target = options.path;
const args = ['clone', url, target];
const process = spawn('git', args);
process.on('close', function () {
return new Promise(function (resolve, reject) {
process.addListener('error', reject);
process.addListener('exit', resolve);
});
});
}
I also tried:
process.on('close', function (code) {
return code;
});
or
process.on('close', function (code) {
return Promise.resolve(code);
});
and several other things like …on('exit', function(code){
return code
})
Any suggestions how to do this?
1. new Promise (function (resolve, reject) { // logic goes here .. In the above line of code, we are using the ‘new’ keyword to create the instance of the promise. As we already know that this is an object available in TypeScript. Also, it has one inner function, which has two parameters named ‘reject’ and ‘resolve’.
We simply destructure the spawn function out of the child_process module and execute it with the OS command as the first argument. The result of executing the spawn function (the child object above) is a ChildProcess instance, which implements the EventEmitter API.
The child_process module enables us to access Operating System functionalities by running any system command inside a, well, child process. We can control that child process input stream, and listen to its output stream. We can also control the arguments to be passed to the underlying OS command, and we can do whatever we want with that command ...
Usually, Node.js allows single-threaded, non-blocking performance but running a single thread in a CPU cannot handle increasing workload hence the child_process module can be used to spawn child processes. The child processes communicate with each other using a built-in messaging system.
You're close, you just need to return the promise from your clone
function (which doesn't need to be async
, since you need to explicitly create the promise). Also, you're hooking the error event at the wrong time (and via the wrong method as far as I can tell):
import {spawn} from 'child_process';
// *** Not async
export default function clone(options: { url: string; path: string; }) {
// *** Return the promise
return new Promise(function (resolve, reject) {
const url = options.url;
const target = options.path;
const args = ['clone', url, target];
const process = spawn('git', args);
process.on('close', function (code) { // Should probably be 'exit', not 'close'
// *** Process completed
resolve(code);
});
process.on('error', function (err) {
// *** Process creation failed
reject(err);
});
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With