返回顺序运行子进程的承诺

returning promises for sequential runing child processes

我正在尝试生成子进程并将其结果放入 Promise 中。 子进程不能同时运行多次

我将 node.js 的 child_process.spawn() 包裹在 Promise 中。 当流程成功退出时,promise 就会履行,否则就会拒绝。 请求在不同时间出现,有时是一个,有时是多个。我需要为每个请求执行相同的命令,甚至可能多次(使用不同或可能相同的选项)来满足请求。但是如果 运行 并行,命令将锁定。所以如果不确保它事先退出就不能 运行。

也许我需要他们排队?

我不知道如何在 JavaScript / Typescript 中执行此操作。忙碌的等待显然不是上帝的主意,但我希望它能解释我想在这里做的事情。

export class RunThingy{

private busy: boolean;

constructor() {
  this.busy = false;
}

private run(options: string[]): Promise<string> {
  return new Promise((resolve, reject) => {
    let stdout: string = '';
    let stderr: string = '';
    while (!this.busy) {             //Problem
      this.busy = true;
      let process: ChildProcess = spawn('processName', options); 
      process.stdout.on('data', (contents) => { stdout += contents; });
      process.stderr.on('data', (contents) => { stderr += contents; });
      process
        .on('error', reject)
        .on('close', function (code) {
          if (code === 0) {
            resolve(stdout);
          } else {
            reject(stderr);
          }
          this.buisy = false;        //Problem
        });
    }
  });
}

编辑:将 command[] 重命名为 options[]

一个承诺只能被拒绝或解决一次。每个过程都必须包含在一个承诺中。这里有一个命题:

export class RunThingy {
    private curCommand: Promise<string> | null

    private run(options: string[]): Promise<string> {
        let next: Promise<string>
        if (this.curCommand) {
            next = this.curCommand.then(
                () => runCommand(options), // the next command will be started after
                () => runCommand(options)  // the current will be resolved or rejected
            )
        } else
            next = runCommand(options)
        next = next.then(stdout => {
            if (next === this.curCommand) // if this is the last command
                this.curCommand = null    // then forget the current command
            return stdout                 // return the command value
        }, err => {
            if (next === this.curCommand) // if this is the last command
                this.curCommand = null    // then forget the current command
            throw err                     // throw again the error
        })
        this.curCommand = next
        return this.curCommand
    }
}

function runCommand(options: string[]): Promise<string> {
    return new Promise((resolve, reject) => {
        let stdout = '';
        let stderr = '';
        let process: ChildProcess = spawn('processName', options);
        process.stdout.on('data', (contents) => { stdout += contents; });
        process.stderr.on('data', (contents) => { stderr += contents; });
        process
            .on('error', reject)
            .on('close', function (code) {
                if (code === 0) {
                    resolve(stdout);
                } else {
                    reject(new Error(stderr));
                }
            });
    });
}

在方法run中,我们检查是否有当前命令。新命令将在当前命令被解析或拒绝后启动。