【问题标题】:Does async function try catch block can wrap a called async function that also may throw an error?异步函数 try catch 块是否可以包装一个调用的异步函数,该函数也可能引发错误?
【发布时间】:2021-04-18 18:42:02
【问题描述】:

我有以下代码:

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 中的正确行为是什么?

【问题讨论】:

  • 这里getJSON async 没有意义,它已经返回了一个承诺并且不包含await(尽管您可以将其重构为使用await)。 outerFunc 将捕获来自getJSONpromise 链中 的错误,即拒绝。
  • @jonrsharpe,我明白了。谢谢

标签: javascript asynchronous error-handling async-await


【解决方案1】:

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

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

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

getAPI 不会自己捕获,只是允许调用者处理可能的错误 - 类似于您的 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 及其调用者处理可能出现的问题。

【讨论】:

  • 在你的第二个例子中,如果 getAPI() return an error it automatically jump to catch` 阻塞并且不会传入 then.. 所以 populateSubComponent 永远不会被调用。不是吗?
  • 对,就是成功函数。如果有错误,它将不会运行。
  • 您不想举例说明在两个不同的地方处理错误的情况吗?
  • 答案中的最后一个 sn-p 就是这样做的。 makeSubComponent 都在内部处理错误并且允许调用者看到发生了错误,因为它返回的 Promise 可以拒绝。
  • 所以您的情况是 getApi 不返回 Errorthen 将与 populateSubComponent 一起运行,这将创建一个将在 makeSubComponent 内捕获的错误?跨度>
猜你喜欢
  • 1970-01-01
  • 2020-01-02
  • 2014-01-06
  • 2019-08-18
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 2017-05-11
  • 2012-07-25
相关资源
最近更新 更多