首页 > 解决方案 > 异步函数 try catch 块是否可以包装一个调用的异步函数,该函数也可能引发错误?

问题描述

我有以下代码:

const getJSON = async function(url, errorMsg = 'Something went wrong') {
  return fetch(url).then(response => {
    if (!response.ok) throw new Error(`${errorMsg} (${response.status})`);

    return response.json();
  });
};

const outerFunc = async function() {
  try {
    let x = await getJSON();
  } catch (err) {
    console.log(err);
  }
}

outerFunc();

我试图在控制台中运行代码并得到一个错误:

VM60:2 Fetch API 无法加载 chrome://new-tab-page/undefined。不支持 URL 方案“chrome”。

我想了解 **outerFunc ** 函数周围的try/catch块是否可以捕获来自被调用的异步函数 ( asyncFunction ) 的错误,或者asyncFunction是否应该自己处理它的错误。我知道在 Java 中可以“传播”错误。JS中的正确行为是什么?

标签: javascriptasynchronouserror-handlingasync-await

解决方案


通常,您希望在可以做一些有用的事情来响应错误的地方捕获错误。通常,这不是调用 API 的地方,而是调用堆栈更远的地方。允许错误自然地向上传播到可以合理处理的地方是一个好主意。

例如,在实际应用程序中,如果存在由 a组成的 catch 块,则console.log通常(并非总是)表明应该在其他地方捕获错误。当出现错误时,通常会想要通知用户出现问题,因此以下类型的模式非常常见:

getAPI()
  .then(populateWithResults)
  .catch((error) => {
    const div = document.querySelector('.errors').appendChild(document.createElement('div'));
    div.textContent = 'There was an unexpected error: ' + error.message;
  });

wheregetAPI没有自己的捕获,而只是允许调用者处理可能的错误 - 类似于您的getJSON函数正在执行的操作。

通常你只想要一个错误被捕获的点,但有时你可能想要在多个地方捕获它——例如,也许一个子组件想要在遇到错误时做一些特别的事情,但它也想要通知来电者有问题。在这种情况下,重新抛出错误可能如下所示:

const makeSubComponent = () => {
  const componentContainer = document.querySelector('.container');
  const populateSubComponent = () => {
    // ...
  };
  return getAPI()
    .then(populateSubComponent)
    .catch((error) => {
      componentContainer.textContent = 'Something went wrong...'
      throw error; // Inform the caller of makeSubComponent of the error
    });
};

允许两者makeSubComponent及其调用者处理可能的问题。


推荐阅读