【问题标题】:Promise.all error handling — make result of one Promise accessible in another Promise's catch?Promise.all 错误处理——让一个 Promise 的结果在另一个 Promise 的捕获中可访问?
【发布时间】:2019-09-25 10:39:58
【问题描述】:

我正在编写一个简单的构建脚本来编译一些文件。剩下的唯一问题是错误处理。它有效,但我想在错误消息中添加其他内容。以下是相关代码的 sn-p:

const promises = []

for (let file of files) {
  promises.push(Promise.all([exec(compile(file)), Promise.resolve(file)]))
}

Promise.all(promises.map(p => p.catch(e => console.log(e))))
.then(result => {
  /* result is now an array with the following pattern:
     [[stdout, filename], [stdout, filename], ...]
   */
});

exec 函数返回一些 stdout,其中包含未说明使用哪个文件的数据。因此,我添加了一个Promise.all,其中包含 exec 函数和一个立即解析并返回文件名的承诺。当我需要将文件写入系统时,我需要从 exec 返回的数据和文件名。因为我仍然希望最后一个then 运行而不管任何错误,我分别处理每个文件的错误(因此.map)。唯一的问题是来自execstdout 没有引用它使用的文件。所以错误信息变得混乱。我想要以下内容:

p.catch(e => console.log(`error happened in ${file}:`, e))

我不确定如何从catch 中访问文件变量。有什么想法吗?

【问题讨论】:

    标签: javascript asynchronous error-handling promise


    【解决方案1】:

    调用函数时应该直接加上catch:

      for (let file of files) {
        promises.push(
           exec(compile(file))
             .then(result => [result, file])
             .catch(error => [error, file])
        );
      }
    
      Promise.all(promises).then(results => {
        //...
      });
    

    【讨论】:

    • 如果我这样做,file 将始终是 files 数组中的最后一项。不知道为什么。
    • @audun 你确定你用过let file 吗?
    • 我的错!我没有,我使用了var。它适用于let。我重写了一些代码以使我的问题更简单,并且我不专心地写了 let.. 谢谢!
    【解决方案2】:

    您可能希望将catch 放在相应file 仍在范围内的循环中:

    Promise.all(files.map(file => 
      Promise.all([
        exec(compile(file)).catch(e => console.log(`error happened in ${file}:`, e)),
        file
      ])
    )).then(result => {
      /* result is now an array with the following pattern:
         [[stdout/undefined, filename], [stdout/undefined, filename], ...]
       */
    });
    

    【讨论】:

    • 漂亮!还要感谢您注意到 Promise.resolve(file) 是多余的。
    • 那为什么还要使用嵌套的Promise.all呢?
    • @JonasWilms 这只是一种廉价的写作方式.then(result => [result, file])。我留下了它,因为 OP 使用了相同的方法。
    猜你喜欢
    • 2019-04-07
    • 1970-01-01
    • 2019-06-29
    • 2017-04-24
    • 2018-03-11
    • 2017-07-31
    • 2020-08-06
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多