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)
}
因为errorTest
是async
,它会总是返回一个promise并且从不保证完成执行在下一条语句开始之前:它是异步。 errorTest
返回,并且您退出 try
block ,很可能在 errorTest
完全运行之前。因此,您的 catch
block 永远不会触发,因为 errorTest
中的任何内容都不会同步抛出异常。
Promise 拒绝和异常是两种不同的失败 channel :Promise 拒绝是异步的,而异常是同步的。 async
会将同步异常(throw
)转换为异步异常(promise 拒绝),但除此之外,这是两个完全不同的系统。
(我之前写过异步函数不会立即开始运行,这是我的错误:As on MDN,async
函数确实会立即开始运行,但会在第一个 处暂停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/