为什么 async 中的 catch 不等待代码触发?
Why doesn't the catch in async await code fire?
是否有任何 .catch()
方法,就像 async await
代码风格的 Promises 一样?
这是一个通过 Promise 编写的代码示例:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
function getData(url){
fetch(url)
.then(response => response.json())
.then(json => console.log(json))
.catch( err => console.log('cannot load api'))
}
getData(apiURL);
getData(badURL);
一个尝试加载数据的简单函数,如果没有,则显示基本错误消息。现在我想把它转录成 async/await
风格的代码,问题是,我真的想不出用 catch()
写这个的方法
我最好的猜测是尝试 try - catch
但 catch 部分不起作用:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
const response = await fetch(url);
try {
const json = await response.json();
console.log(json);
} catch (e) {
console.log('cannot load api');
}
}
getData(apiURL);
getData(badURL);
这会很好地加载对象 API,但似乎永远不会进入 catch{}
块,尽管传递不正确 url.
知道我做错了什么吗?
As pointed out in the comments by @l-portet, this is because the code inside try { }
block does not actually fail!
.json()
将 return 承诺,无论解析的正文文本 的内容如何,因此即使初始 fetch()
失败,您仍然可以对其调用 .json()
- 尽管它是完全多余的,因为它 return 没有任何意义。
将 fetch()
请求放入 try { }
块中确实会产生预期的行为:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
try {
const response = await fetch(url);
const json = await response.json();
console.log(json);
} catch (e) {
console.log('cannot load api');
}
}
getData(apiURL);
getData(badURL);
你应该知道的一件事是,当一个 async
函数被执行时,它 总是 return 一个承诺 ,不管函数的退出条件功能。
如果该函数具有明确的 return
(或在不崩溃的情况下完成),promise 将 resolved 为它 returned 的值(或undefined
如果没有显式 return),如果函数抛出,promise 将被拒绝,传递抛出的错误对象。
知道你可以简单地处理你使用函数的错误,例如:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
const response = await fetch(url);
return await response.json();
}
getData(apiURL).then(data => console.log(data));
getData(badURL).catch(err => console.log('error:', err));
恕我直言,在函数 use-case 处密切处理错误更有意义,因为通常情况下,当您期望出现错误时,是因为我们有办法处理它(也许尝试另一个 API url 在这个例子中)。
我最近一直在使用的一种模式是按照 [error, value]
的约定(类似于 Go 编程语言的方式)以解析 return 元组的方式包装承诺handle async error),例如,您可以在特定的 getData
调用中处理错误,例如:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
const response = await fetch(url);
return await response.json();
}
// simple utility function
const safePromise = promise =>
promise.then(data => [null, data]).catch(err => [err, undefined]);
(async () => {
const [err, json] = await safePromise(getData(apiURL))
if (err) {
// handle the error
}
console.log(json)
const [error, data] = await safePromise(getData(badURL))
if (error) {
console.log('Error:', error);
}
})()
检查以下基本包含此模式的库:
是否有任何 .catch()
方法,就像 async await
代码风格的 Promises 一样?
这是一个通过 Promise 编写的代码示例:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
function getData(url){
fetch(url)
.then(response => response.json())
.then(json => console.log(json))
.catch( err => console.log('cannot load api'))
}
getData(apiURL);
getData(badURL);
一个尝试加载数据的简单函数,如果没有,则显示基本错误消息。现在我想把它转录成 async/await
风格的代码,问题是,我真的想不出用 catch()
我最好的猜测是尝试 try - catch
但 catch 部分不起作用:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
const response = await fetch(url);
try {
const json = await response.json();
console.log(json);
} catch (e) {
console.log('cannot load api');
}
}
getData(apiURL);
getData(badURL);
这会很好地加载对象 API,但似乎永远不会进入 catch{}
块,尽管传递不正确 url.
知道我做错了什么吗?
As pointed out in the comments by @l-portet, this is because the code inside
try { }
block does not actually fail!
.json()
将 return 承诺,无论解析的正文文本 的内容如何,因此即使初始 fetch()
失败,您仍然可以对其调用 .json()
- 尽管它是完全多余的,因为它 return 没有任何意义。
将 fetch()
请求放入 try { }
块中确实会产生预期的行为:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
try {
const response = await fetch(url);
const json = await response.json();
console.log(json);
} catch (e) {
console.log('cannot load api');
}
}
getData(apiURL);
getData(badURL);
你应该知道的一件事是,当一个 async
函数被执行时,它 总是 return 一个承诺 ,不管函数的退出条件功能。
如果该函数具有明确的 return
(或在不崩溃的情况下完成),promise 将 resolved 为它 returned 的值(或undefined
如果没有显式 return),如果函数抛出,promise 将被拒绝,传递抛出的错误对象。
知道你可以简单地处理你使用函数的错误,例如:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
const response = await fetch(url);
return await response.json();
}
getData(apiURL).then(data => console.log(data));
getData(badURL).catch(err => console.log('error:', err));
恕我直言,在函数 use-case 处密切处理错误更有意义,因为通常情况下,当您期望出现错误时,是因为我们有办法处理它(也许尝试另一个 API url 在这个例子中)。
我最近一直在使用的一种模式是按照 [error, value]
的约定(类似于 Go 编程语言的方式)以解析 return 元组的方式包装承诺handle async error),例如,您可以在特定的 getData
调用中处理错误,例如:
const apiURL = 'https://jsonplaceholder.typicode.com/todos/1';
const badURL = 'zhttps://wcaf.fajfkajf.gg'
async function getData(url){
const response = await fetch(url);
return await response.json();
}
// simple utility function
const safePromise = promise =>
promise.then(data => [null, data]).catch(err => [err, undefined]);
(async () => {
const [err, json] = await safePromise(getData(apiURL))
if (err) {
// handle the error
}
console.log(json)
const [error, data] = await safePromise(getData(badURL))
if (error) {
console.log('Error:', error);
}
})()
检查以下基本包含此模式的库: