【问题标题】:Javascript forEach swallowing exceptions [duplicate]Javascript forEach吞咽异常[重复]
【发布时间】:2020-05-07 20:29:56
【问题描述】:

我正在尝试在 JavaScript 中使用 forEach 循环和 async 回调来循环数组。问题是当我抛出异常时,它会给出

(node:2500) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 6)

虽然我在forEach 之后有一个catch 块。这是我的代码

async function func() {
    try {
        array.forEach(async (e) => {
            try {
                let bom = await BOMChild.findOne({
                    where: { id: e.id },
                });

                if (bom.BOMProductId || bom.BOMProductId === 0) {
                    throw {
                        name: " error",
                        description: `Description `,
                    };
                }
            } catch (e) {
                throw e;
            }
        });
    } catch (e) {
        //exception caught
    }
}

我做错了什么以及解决此问题的可能方法是什么。 TIA

【问题讨论】:

  • throw e; 不会被扔到.forEach 之外。我很难解释它是如何工作的。尝试阅读有关lambda 的信息,具体是做什么的。也许这会有所帮助:vinta.com.br/blog/2015/javascript-lambda-and-arrow-functions
  • forEach 是一个调用你的实现的函数。在forEach 中,我敢肯定,它是一个try-catch,它吸收了所有实现错误(比如异常,即使你抛出它)不会破坏forEach
  • @KunLun 没有。您可以轻松地从回调中抛出异常以停止forEach。它返回的承诺稍后会拒绝,这无济于事。

标签: javascript asynchronous promise async-await es6-promise


【解决方案1】:

不幸的是,没有安全的方法可以将async 回调与forEach 一起使用。最简单的解决方案是以async 的方式重新实现forEach,如下所示。请注意,asyncForEach 本身会返回一个承诺,因此您需要使用 .then() 来继续您的程序。

const asyncForEach = async (array, callback) => {
  try {
    for (let i = 0; i < array.length; i++) {
      await callback(array[i]);
    }
  }
  catch (ex) {
     // handle exception here.
  }
}

asyncForEach(array, async () => {
  let bom = await BOMChild.findOne({
    where: { id: e.id },
  });

  if (bom.BOMProductId || bom.BOMProductId === 0) {
    throw {
      name: " error",
      description: `Description `,
    };
  }
}).then(() => {
  // continue program.
});

如果您想使用更简洁但更令人困惑的解决方案来测试您的承诺印章,请查看Promise.all()

【讨论】:

    猜你喜欢
    • 2016-01-21
    • 2013-09-09
    • 1970-01-01
    • 2017-01-26
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    相关资源
    最近更新 更多