You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript命令链Promise问题:第二个命令先执行,需等待第一个完成

问题分析与解决

你的Orchestrator类的串行逻辑本身是正确的——run方法通过for...of循环逐个await命令的execute方法,理论上应该按顺序执行第一个命令完成后再执行第二个。出现第二个命令先执行的情况,问题几乎肯定出在FirstCommand依赖的BashRunner.run方法没有正确等待Shell脚本执行完成。

排查核心点

你的FirstCommand.execute方法是async的,并且用await调用了bashRunner.run(),但如果bashRunner.run()没有返回一个真正等待脚本执行结束的Promise,就会导致FirstCommand的execute提前完成,让Orchestrator立刻开始执行第二个命令。

正确的BashRunner实现

确保BashRunner.run方法正确监听子进程的退出事件,在脚本执行完成(或出错)后才resolve/reject Promise:

import { spawn } from 'child_process';

export class BashRunner {
  async run(scriptPath: string): Promise<void> {
    return new Promise((resolve, reject) => {
      // 启动Shell脚本进程
      const process = spawn('bash', [scriptPath]);

      // 监听进程退出事件
      process.on('exit', (code) => {
        if (code === 0) {
          resolve(); // 脚本成功执行完毕,resolve Promise
        } else {
          reject(new Error(`脚本执行失败,退出码:${code}`));
        }
      });

      // 监听进程启动失败事件
      process.on('error', (error) => {
        reject(new Error(`无法启动脚本:${error.message}`));
      });

      // 可选:将脚本的输出同步到控制台,方便调试
      process.stdout.pipe(process.stdout);
      process.stderr.pipe(process.stderr);
    });
  }
}

额外检查项

  • 确认FirstCommand中正确导入了join:
    import { join } from 'path'; // 补充这个导入,避免找不到脚本路径
    
  • 验证你的Command接口定义正确,确保execute方法返回Promise<void>:
    export interface Command {
      execute(): Promise<void>;
    }
    

为什么原代码逻辑没问题?

再看你的Orchestrator和Main代码:

  • withCommand只是将命令加入数组,没有提前执行
  • run方法中的for...of循环配合await会强制串行执行每个命令的execute方法,前一个命令的Promise不resolve,循环不会进入下一次迭代

所以只要修复BashRunner的run方法,让它真正等待脚本完成,就能解决顺序问题。

内容的提问来源于stack exchange,提问作者vidola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:15:42