【问题标题】:Using Try/Catch with Promise.all将 Try/Catch 与 Promise.all 一起使用
【发布时间】:2019-05-27 14:51:21
【问题描述】:

我最近一直在阅读有关 async/await 并使用 try 和 catch 处理 Promise 拒绝的内容,并将其应用于我的一些旧代码。

我有以下:

async function() {
    try {
        await Promise.all([some functions]);
        doIfNoError();
    } catch (error) {
        console.log(error);
    }

我传递给 Promise.all 的函数都遵循以下格式:

async function() {
    some code
    if (some condition) {
        return true
    } else {
        throw false
    }
 }

我打算如果传递给 Promise.all 的任何函数拒绝,就会显示拒绝。如果没有任何函数拒绝,则 doIfNoError 应该触发。但是,doIfNoError 有时会在不应该触发时触发,并且我收到错误“Unhandled Promise Rejection”。

【问题讨论】:

  • 也许你的doIfNoError 函数正在做一些引发错误的工作。你能在这里添加一个真实的例子吗?
  • 还有你在 Promise.all 中传递的函数,尝试传递一个 Promise。它将拒绝或解决承诺,而不仅仅是返回或抛出一些值。例如:Promise.resolve(true) 或 Promise.reject(false)
  • 您必须调用您的函数并将数组中的结果承诺传递给Promise.all,而不是函数本身。
  • 请贴出实际代码。您的try/catch 代码很好,它必须是调用或async functions 的内容。
  • await Promise.all([some functions]) 应该是await Promise.all([some promises]);

标签: javascript node.js async-await


【解决方案1】:

1) throw false - 这没有意义,你不应该抛出一个布尔值,而是一个 Error 的实例。

2) catch 仅在抛出错误或承诺被“拒绝”时触发(注意:reject 和 throw 具有带有异步等待的 same effect)。相比之下: async-await 不会将布尔值为 false 的 Promise 解析为异常。因此,如果您希望捕获块启动,请确保您 throw 错误或 reject 承诺。如果您 reject,请将异常作为参数传递给拒绝,例如(Promise.reject(new Error("Something went wrong")).

除了我上面提到的,你的代码看起来还不错。

【讨论】:

  • 你可以抛出任何值,它不一定是Error的实例,即throw 123
  • 可以抛出任何东西,但真的没有理智的理由抛出任何非错误的东西。
【解决方案2】:

尝试充分发挥 Promise 的潜力,其中包括一个用于处理被拒绝的 Promise 的 catch 块。请注意,如果doIfNoError 也抛出错误,它将被catch 捕获。

async function() {
    await Promise.all([some promises])
    .then(doIfNoError) // Promise.all resolved
    .catch(console.log) // Promise.all has at least one rejection
}

promiseAll = async (promises) => {
  await Promise.all(promises)
  .then(doIfNoError) // Promise.all resolved
  .catch(console.log) // Promise.all has at least one rejection
}
    
doIfNoError = () => console.log('No errors');

promiseAll([Promise.resolve(), 1, true, () => (false)]);
promiseAll([Promise.resolve(), 1, true, Promise.reject('rejected: because reasons'), Promise.resolve()]);

【讨论】:

    【解决方案3】:

    实际上,try/catch 确实可以与Promise.all() 配合使用很好

    这里有一个sn-p来证明:

    async function p1() {
      return 1;
    }
    async function boom() {
      throw new Error('boom');
    }
    
    // expected output: 'boom', ["value before Promise.all"]
    async function asyncCall() {
      let all = ['value before Promise.all'];
      try {
        all = await Promise.all([p1(), boom()]);
      } catch(e) {
        console.log(e.message);
      }
      console.log(JSON.stringify(all));
    }
    
    asyncCall();

    【讨论】:

      猜你喜欢
      • 2015-02-01
      • 2017-11-25
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 2020-09-24
      相关资源
      最近更新 更多