首页 > 解决方案 > 理想地使用 Try/Catch

问题描述

我有两个功能,控制器和服务。这是服务代码。

const getVersion = async (type) => {
  const version = await Version.findOne({ TYPE: type }, { _id: false, VERSION: true })

  return version
}

并且控制器代码调用服务中存在的getVersion函数

const getVersion = async (req, res) => {
  try {
    ......
    const version = await Version.findOne({ TYPE: type }, { _id: false, VERSION: true })
    ......
  } catch (error) {
    ......
  }
}

所以我的问题是,在 getVersion() 函数中,有一个异步调用。我是否应该将函数包装在 try catch 中,所以它看起来像这样:

const getVersion = async (type) => {
  try {
    const version = await Version.findOne({ TYPE: type }, { _id: false, VERSION: true })
    return version
  } catch (error) {
    return error
  }
}

或者我应该像原来那样在函数的根目录中使用 try/catch 吗?这两种方法的优缺点是什么?谢谢你。

标签: javascriptnode.js

解决方案


这是一个反模式 -

const getVersion = async (type) => {
  try {
    const version = await Version.findOne({ TYPE: type }, { _id: false, VERSION: true })
    return version
  } catch (error) {
    return error
  }
}

原因是您的函数被标记为async它已经返回了一个 Promise。所以它要么解决version要么拒绝error. 1

这是写它的惯用方式 -

const getVersion = type =>
  Version.findOne({ TYPE: type }, { _id: false, VERSION: true })

现在,当您调用它时,将解析有效的版本响应,或者将拒绝某些错误 -

getVersion("foo").then(console.log, console.error)

1.在你的getVersion你实际上解决了成功案例错误案例。这有效地消除了错误,而不是让它冒泡给调用者。通过拒绝错误,您允许调用者适当地处理它。


这是一个类似的反模式 -

function foo (s = "") {
  if (s.length > 5)
    return true
  else
    return false
}

哪个是不太惯用的版本 -

function foo (s = "") {
  return s.length > 5
}

或作为箭头函数 -

const foo = (s = "") =>
  s.length > 5

推荐阅读