Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make child_process.spawn return a Promise in my TypeScript module?

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?

like image 641
fabianmoronzirfas Avatar asked Nov 08 '18 08:11

fabianmoronzirfas


People also ask

How to create a new promise in typescript?

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’.

How do I execute a spawn function from a child process?

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.

What is the use of the child_process module?

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 ...

What is child_process in Node JS?

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.


1 Answers

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);
    });
  });
}
like image 66
T.J. Crowder Avatar answered Oct 18 '22 00:10

T.J. Crowder