【问题标题】:Why can't try/catch handle error throw in Promise constructor为什么不能在 Promise 构造函数中尝试/捕获处理错误抛出
【发布时间】:2022-08-19 22:51:02
【问题描述】:

这段代码得到unhandledRejection 错误,我不知道为什么。

如果在try/catch中抛出Error,不应该被Catch Expression捕获吗?

async function main () {
  try {
    await run(throwError)
  } catch (error) {
    console.log(\'main catch error\', error);
  }
}

async function run (callback) {
  return new Promise(async resolve => {
    await throwError()
  });
}

async function throwError () {
  throw new Error(\'custom error\')
}

process.on(\'unhandledRejection\', (reason, promise) => {
  console.log(\'unhandledRejection - reason\', reason, promise);
})

main()

标签: javascript node.js


【解决方案1】:

在这种情况下你不想抛出错误,你想调用reject

  return new Promise((resolve, reject) => {
    reject('custom error')
  });

如果抛出的错误超出了您的控制范围,您可以在承诺实现中捕获它并在这种情况下拒绝。

【讨论】:

    【解决方案2】:

    它没有被捕获,因为您将 async 函数传递给 new Promiseasync 函数中的错误拒绝了函数返回的承诺。 Promise 构造函数不执行任何您传递给它的函数返回的承诺(该函数的返回值被完全忽略),因此拒绝未处理。这是 Promise 反模式之一:不要向无法处理它的东西提供 Promise(例如网络上的 addEventListener,或 Promise 构造函数,或 forEach,...)。

    同样,完全没有理由在您的async 函数中使用new Promiseasync 函数已经回报承诺。这是另一种反模式,有时称为explicit promise construction anti-pattern

    如果您删除了不必要的new Promise,它会按您的预期工作(我还更新了run 以调用callback,而不是忽略它并直接调用throwError):

    async function main() {
        try {
            await run(throwError);
        } catch (error) {
            console.log("main catch error", error);
        }
    }
    
    async function run(callback) {
        await callback();
    }
    
    async function throwError() {
        throw new Error("custom error");
    }
    
    process.on("unhandledRejection", (reason, promise) => {
        console.log("unhandledRejection - reason", reason, promise);
    });
    
    main();
    

    【讨论】:

    • 谁会否决这个答案,请告诉我,具体来说,您认为它有什么问题?
    • 本手册new Promise() 调用可能只是为了通用 MRE。
    猜你喜欢
    • 2020-05-09
    • 2020-03-16
    • 2015-12-06
    • 2016-02-12
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 2022-12-10
    • 2020-06-19
    相关资源
    最近更新 更多