javascript - 为什么 try {} .. catch() 不能与 async/await 函数一起使用?

标签 javascript promise try-catch

const errorTest = async() => { 

  const result = await $.get("http://dataa.fixer.io/api/latest?access_key=9790286e305d82fbde77cc1948cf847c&format=1");

  return result;

}


 try { 
  errorTest()
 }
 catch(err) { 
   console.log("OUTSIDE ERROR!" + err)
 }

该 URL 故意不正确以引发错误,但外部 catch() 它没有捕获它。为什么?

如果我使用 then()catch() 代替,它可以工作。

errorTest()
.then(val=> console.log(val))
.catch(err=> console.error("ERROR OCCURRED"))

这行得通,但 try {..} catch() 不行。为什么?

我不断收到 Uncaught (in promise) 错误

最佳答案

async function errorTest() { /* ... */ }

try { 
  errorTest()
}
catch(err) { 
  console.log("OUTSIDE ERROR!" + err)
}

因为errorTestasync,它会总是返回一个promise并且从不保证完成执行在下一条语句开始之前:它是异步errorTest 返回,并且您退出 try block ,很可能在 errorTest 完全运行之前。因此,您的 catch block 永远不会触发,因为 errorTest 中的任何内容都不会同步抛出异常。

Promise 拒绝和异常是两种不同的失败 channel :Promise 拒绝是异步的,而异常是同步的。 async 会将同步异常(throw)转换为异步异常(promise 拒绝),但除此之外,这是两个完全不同的系统。

(我之前写过异步函数不会立即开始运行,这是我的错误:As on MDNasync 函数确实会立即开始运行,但会在第一个 处暂停await 点,但即使它们立即发生,它们抛出的错误也会转换为 Promise 拒绝。)

function errorTest() {
  return new Promise(/* ... */);  // nothing throws!
}

function errorTestSynchronous() {
  throw new Error(/* ... */);     // always throws synchronously
}

function errorTestMixed() {
  // throws synchronously 50% of the time, rejects 50% of the time,
  // and annoys developers 100% of the time
  if (Math.random() < 0.5) throw new Error();
  return new Promise((resolve, reject) => { reject(); });
}

在这里您可以看到各种形式的 throw 。第一个,errorTest,与你的完全等价:async 函数就像你将代码重构为一个新的 Promise 一样工作。第二个,errorTestSynchronous,同步抛出:它会触发你的 catch block ,但是因为它是同步的,你已经失去了对其他异步操作使用react的机会,比如你的 $.get 调用。最后,errorTestMixed 可能会以两种方式失败:它可以抛出,也可以拒绝 promise 。

由于所有同步错误都可以异步处理,并且所有异步代码都应该有 .catch() promise 链接错误,因此在同一个函数中很少需要两种类型的错误,它是通常更好的方式是始终为 async 或 Promise-returning 函数使用异步错误——即使这些错误来自 async 函数中的 throw 语句。


在 Ayotunde Ajayi 的回答中,您可以通过使用 await 将异步错误转换为同步显示来解决此问题,因为 await 会将 Promise 失败解包回 throw异常(exception):

// within an async function
try { 
  await errorTest()
}
catch(err) { 
   console.log("OUTSIDE ERROR!" + err)
}

但在幕后,它将完全按照您在问题中的建议显示:

errorTest()
    .then(val=> console.log(val))
    .catch(err=> console.error("ERROR OCCURRED"))

关于javascript - 为什么 try {} .. catch() 不能与 async/await 函数一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68102365/

相关文章:

javascript - 如何将 ID 添加到动态生成的 href?

javascript - 如何使用 style.left 从右向左移动图像?

javascript - 未处理的 Promise 异常

javascript - 有没有办法在解决 promise 之前填充 JSON 对象

c++ - 使用 assert c++ 测试一个函数

php - 具有数据库事务的 Laravel Controller-Model 异常处理结构

javascript - native 应用程序和 chrome-extension 之间的连接在一段时间后中断

javascript - 尝试将所有 "p"标签更改为以下代码中指定的颜色

java - 使用 try-catch-finally 的 Java 7 try-with-resources 字节码是什么?

javascript - 什么时候需要创建延迟?