【问题标题】:How to resolve a list of dynamically created Promises?如何解析动态创建的 Promise 列表?
【发布时间】:2020-08-31 07:14:05
【问题描述】:

我正在编写一个 git pre-commit 钩子,我希望能够向它传递一个要执行的命令数组,让它执行它们,如果有任何失败抛出一个错误。这些命令的示例可能是运行测试套件或构建。

我在使用 Node 的 child_process exec 命令的承诺版本动态执行此操作时遇到问题。

到目前为止,我有一个包含 2 个示例命令的配置文件:

config.js

const config = {
  onPreCommit: ['git --version', 'node -v'],
};

module.exports = config;

如果我使用此代码手动传递值,我会按照预期从命令中获得正确的值来实现承诺对象:

预提交挂钩

function preCommit() {
  if (config.onPreCommit && config.onPreCommit.length > 0) {
    Promise.allSettled([
      exec(config.onPreCommit[0]),
      exec(config.onPreCommit[1]),
    ]).then((results) => results.forEach((result) => console.log(result)));
  }
}

preCommit();

但是,如果我尝试像下面这样动态地执行此操作,则会引发错误:

function preCommit() {
  if (config.onPreCommit && config.onPreCommit.length > 0) {
    const cmdPromises = config.onPreCommit.map((cmd, i) => {
      return new Promise((resolve, reject) => {
        exec(cmd[i])
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
    });

    Promise.allSettled(cmdPromises).then((results) =>
      results.forEach((result) => console.log(result))
    );
  }
}

preCommit();

承诺被拒绝:

Error: Command failed: o 'o' is not recognized as an internal or external command, operable program or batch file.

Error: Command failed: o
  'o' is not recognized as an internal or external command,
  operable program or batch file.

【问题讨论】:

  • 虽然对此进行了更多检查,但我认为此语句是有效的“异步执行的 exec 函数可用于运行 shell 命令。但是,如果您想等待其结果,那么它是变得繁琐:不是返回 Promise,而是回调"
  • 我认为问题可能是exec(cmd[i]),应该是exec(cmd)。 (“o”可能是“节点”[1])

标签: javascript node.js es6-promise githooks


【解决方案1】:

感谢comment by mtkopone,问题出在我的地图功能中。

已通过将 exec(cmd[i]) 更改为 exec(cmd) 修复

还更新了函数,因此钩子可以按预期工作:

function preCommit() {
  if (config.onPreCommit && config.onPreCommit.length > 0) {
    // Loop through scripts passed in and return a promise that resolves when they're done
    const cmdPromises = config.onPreCommit.map((cmd) => {
      return new Promise((resolve, reject) => {
        exec(cmd)
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
    });

    // Make sure all scripts been run, fail with error if any promises rejected
    Promise.allSettled(cmdPromises)
      .then((results) =>
        results.forEach((result) => {
          if (result.status === 'rejected') {
            console.log(result.reason);
            process.exit(1);
          }
        })
      )
      .then(() => {
        // If no errors, exit with no errors - commit continues
        process.exit(0);
      });
  }
}

preCommit();

【讨论】:

    猜你喜欢
    • 2020-05-30
    • 2015-11-15
    • 2021-03-18
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 2018-12-28
    • 1970-01-01
    相关资源
    最近更新 更多