JavaScript:使用Async/AWAIT和THEN/CATCH处理异步错误之间的差异

JavaScript: differences between async error handling with async/await and then/catch(JavaScript:使用Async/AWAIT和THEN/CATCH处理异步错误之间的差异)
本文介绍了JavaScript:使用Async/AWAIT和THEN/CATCH处理异步错误之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想先发制人地说,我熟悉异步/等待和在JavaScript中的承诺,所以不需要为此将我链接到一些MDN页面。

我有一个获取用户详细信息并将其显示在UI上的函数。


async function someHttpCall() {
  throw 'someHttpCall error'
}
async function fetchUserDetails() {
  throw 'fetchUserDetails error'
}

function displayUserDetails(userDetails) {
  console.log('userDetails:', userDetails)
}

async function fetchUser() {
  try {
    const user = await someHttpCall()
    try {
      const details = await fetchUserDetails(user)
      returndisplayUserDetails(details)
    } catch (fetchUserDetailsError) {
      console.log('fetching user error', fetchUserDetailsError)
    }
  } catch (someHttpCallError) {
    console.log('networking error:', someHttpCallError)
  }
}

它首先通过someHttpCall进行HTTP调用,如果成功,则转到fetchUserDetails,如果也成功,则我们通过returndisplayUserDetails显示有关UI的详细信息。

如果someHttpCall失败,我们将停止并不进行fetchUserDetails调用。换句话说,我们希望将someHttpCall的错误处理和fetchUserDetails的数据处理分开

我编写的函数包含嵌套的try catch块,如果嵌套变得很深,则不能很好地伸缩,我正尝试使用普通thencatch重写它以提高可读性

这是我的第一次尝试

function fetchUser2() {
  someHttpCall()
    .then(
      (user) => fetchUserDetails(user),
      (someHttpCallError) => {
        console.log('networking error:', someHttpCallError)
      }
    )
    .then(
      (details) => {
        displayUserDetails(details)
      }, //
      (fetchUserDetailsError) => {
        console.log('fetching user error', fetchUserDetailsError)
      }
    )
}
这样做的问题是,第二个then将运行,即displayUserDetails即使someHttpCall失败。为了避免这种情况,我不得不让前面的.catch块抛出

这就是更新版本

function fetchUser2() {
  someHttpCall()
    .then(
      (user) => fetchUserDetails(user),
      (someHttpCallError) => {
        console.log('networking error:', someHttpCallError)
        throw someHttpCallError
      }
    )
    .then(
      (details) => {
        displayUserDetails(details)
      }, //
      (fetchUserDetailsError) => {
        console.log('fetching user error', fetchUserDetailsError)
      }
    )
}

但是,现在第二个接球将作为抛出的结果被调用。因此,当someHttpCall失败时,在我们处理了someHttpCallError错误之后,我们将进入这个块(fetchUserDetailsError) => { console.log('fetching user error', fetchUserDetailsError) },这并不好,因为fetchUserDetails从未被调用过,所以我们不需要处理fetchUserDetailsError(我知道someHttpCallError在这种情况下变成了fetchUserDetailsError)

我可以在其中添加一些条件检查来区分这两个错误,但这似乎不太理想。因此,我想知道如何通过使用.then.catch在这里实现相同的目标来改进这一点。

推荐答案

我想知道如何通过使用.then.catch来改进这一点,以在这里实现相同的目标

如果您想要复制相同的行为,则无法避免嵌套:

function fetchUser2() {
  return someHttpCall().then(
    (user) => {
      return fetchUserDetails(user).then(
        (details) => {
          return displayUserDetails(details)
        },
        (fetchUserDetailsError) => {
          console.log('fetching user error', fetchUserDetailsError)
        }
      )
    },
    (someHttpCallError) => {
      console.log('networking error:', someHttpCallError)
      throw someHttpCallError
    }
  )
}

(完全等同于try/catch将使用.then(…).catch(…) instead of .then(…, …),但you might not actually want that。)

我编写的函数是[嵌套的],如果嵌套变得很深,它就不能很好地伸缩,而我正试图重写它以提高可读性[…]

为此,我建议将await.catch()结合使用:

async function fetchUser() {
  try {
    const user = await someHttpCall().catch(someHttpCallError => {
      throw new Error('networking error', {cause: someHttpCallError});
    });
    const details = await fetchUserDetails(user).catch(fetchUserDetailsError => {
      throw new Error('fetching user error', {cause: fetchUserDetailsError});
    });
    return displayUserDetails(details);
  } catch (someError) {
    console.log(someError.message, someError.cause);
  }
}

(Errorcause选项仍然很新,您可能需要一个填充)

这篇关于JavaScript:使用Async/AWAIT和THEN/CATCH处理异步错误之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)