如何让 child_process.spawn 在我的 TypeScript 模块中返回一个 Promise?

fab*_*fas 6 spawn child-process async-await typescript

我正在尝试编写一个child_process.spawn用于克隆 git repo 并返回一个 Promise的小模块,但它在我身上失败了。当我使用 spawnSync 时,它可以工作。

这是有效的同步代码。

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);
}
Run Code Online (Sandbox Code Playgroud)

这是失败并返回的异步代码 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);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)

我也试过:

process.on('close', function (code) {
   return code;
  });
Run Code Online (Sandbox Code Playgroud)

或者

process.on('close', function (code) {
   return Promise.resolve(code);
  });
Run Code Online (Sandbox Code Playgroud)

和其他一些事情,比如 …on('exit', function(code){ return code })

任何建议如何做到这一点?

T.J*_*der 12

你已经接近了,你只需要从你的clone函数中返回承诺(不需要是async,因为你需要明确地创建承诺)。此外,您在错误的时间(据我所知通过错误的方法)挂钩了错误事件:

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);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)