【问题标题】:Why doesn't the catch in async await code fire?为什么异步等待代码中的捕获不触发?
【发布时间】:2019-10-10 04:04:30
【问题描述】:

有没有类似async await 代码风格的 Promises 的 .catch() 方法?

这是一个通过 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。

知道我做错了什么吗?

【问题讨论】:

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


【解决方案1】:

正如@l-portet 在 cmets 中指出的那样,这是因为 try { } 块内的代码实际上并没有失败!

.json() 将返回一个承诺,无论解析后的正文内容如何,因此即使最初的 fetch() 失败,您仍然可以在其上调用 .json() - 尽管它是完全多余,因为它不会返回任何有意义的东西。

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);

【讨论】:

    【解决方案2】:

    您应该注意的一件事是,当 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));

    恕我直言,在您有函数用例的地方密切处理错误更有意义,因为通常当您期望出现错误时是因为我们有办法处理它(也许在这个例子中尝试另一个 API url) .

    我最近一直在使用的一种模式是按照 [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);
      }
    })()

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

    【讨论】:

      猜你喜欢
      • 2014-12-03
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 2023-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多