简体   繁体   English

async function try catch 块是否可以包装一个也可能引发错误的调用 async function?

[英]Does async function try catch block can wrap a called async function that also may throw an error?

I have the following code:我有以下代码:

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

I tried to run the code inside the console and get an error:我试图在控制台中运行代码并出现错误:

VM60:2 Fetch API cannot load chrome://new-tab-page/undefined. VM60:2 Fetch API 无法加载 chrome://new-tab-page/undefined。 URL scheme "chrome" is not supported. URL 方案“chrome”不受支持。

I want to understand if the try/catch block that surrounds the **outerFunc ** function can catch an error that will come from the called async function ( asyncFunction ), or asyncFunction should handle its error by himself.我想了解 **outerFunc ** function 周围的try/catch块是否可以捕获来自调用的异步 function ( asyncFunction ) 的错误,或者asyncFunction应该自己处理它的错误。 I know that in Java it's ok to "propagate" the error.我知道在 Java 中可以“传播”错误。 What is the correct behavior in JS? JS 中的正确行为是什么?

Generally, you want to catch errors at a point where you can do something useful in response to the error.通常,您希望在某个点捕获错误,以便您可以对错误做出有用的响应。 Often, this is not the point where the API is called, but somewhere further up the call stack.通常,这不是调用 API 的点,而是调用堆栈更上层的某个地方。 Allowing errors to naturally propagate upwards to where they can be handled reasonably is a fine idea.允许错误自然向上传播到可以合理处理的地方是一个好主意。

For example, in a real application, if there's a catch block which is composed solely of a console.log , that's often (not always) an indication that the error should be caught somewhere else.例如,在实际应用程序中,如果有一个console.log组成的 catch 块,这通常(并非总是)表明应该在其他地方捕获错误。 When there's an error, one will often want to inform the user that there was a problem, so the following sort of pattern is very common:当出现错误时,人们通常会想通知用户出现了问题,因此以下这种模式非常常见:

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

where getAPI does no catching of its own, but simply allows the caller to handle possible errors - similar to what your getJSON function is doing.其中getAPI不会自己捕获,而只是允许调用者处理可能的错误 - 类似于您的getJSON function 正在做的事情。

Usually you'll only want one point where an error is caught, but occasionally you might want to catch it in multiple places - for example, perhaps a sub-component wants to do something in particular when an error is encountered, but it also wants to notify the callers that there's a problem.通常你只想要一个错误被捕获的点,但偶尔你可能想要在多个地方捕获它 - 例如,也许一个子组件想要在遇到错误时做一些特别的事情,但它也想要通知呼叫者有问题。 In such cases, re-throwing the error could look like:在这种情况下,重新抛出错误可能如下所示:

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

allowing both makeSubComponent and its caller to deal with possible problems.允许makeSubComponent及其调用者处理可能出现的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM