为什么异步等待代码中的陷阱没有触发?

时间:2019-05-23 14:37:47

标签: javascript ecmascript-6 async-await try-catch es6-promise

是否有像.catch()那样的Promises的async await方法?

这是通过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,但抓取部分不起作用:

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,但即使传递了错误的url,也似乎从未进入catch{}块。

知道我在做什么错吗?

2 个答案:

答案 0 :(得分:2)

  

正如@ l-portet的注释所指出的,这是因为try { }块中的代码实际上并没有失败!

.json()将返回一个promise,无论所解析的正文文本的内容如何,因此即使初始fetch()失败,您仍然可以调用{{1} }-尽管它完全是多余的,因为它不会返回任何有意义的东西。

.json()请求放入fetch()块中会导致预期的行为:

try { }

答案 1 :(得分:1)

您应该了解的一件事是,执行async函数时,无论函数的退出条件如何,它都会始终返回一个诺言

如果函数具有显式的return(或完整完成而不会崩溃),则承诺将被解析为其返回的值(如果没有显式,则返回undefined返回),如果函数抛出异常,则将通过传递抛出的错误对象来拒绝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));

在您有函数用例的地方,IMHO仔细处理错误更有意义,因为通常在您希望出现错误的情况下,这是因为我们有一种处理错误的方法(可以在此示例中尝试其他API网址)

我最近使用的一种模式是按照[error, value]的约定(类似于Go编程语言处理异步错误的方式),用它们解决返回元组的方式包装promise。例如,您可以在特定的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);
  }
})()

检查以下基本提供此模式的库: