理想情况下使用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的原始函数一样?这两种方法的优点和缺点是什么?非常感谢。

这是一个反模式-

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,要么拒绝error1

这是写它的惯用方法-

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

我建议您保持原样。不需要在不同的地方添加try-catch来处理相同的异常。假设您正在将异常消息记录到数据库中。如果catch在2个位置,那么您最终将在Db中写入2个日志。它错误地认为发生了2个异常!

您应该只处理实际异步获取数据的代码(即可能成功或失败(。例如,此行-const version = await Version.findOne({ TYPE: type }, { _id: false, VERSION: true })。所以,如果失败,Catch块就会运行。你应该用try/catch 包装整个功能

我应该将函数包装在try-catch 中吗

每当解析promise时,都需要包装异步函数

await语句意味着有一个异步调用可能会失败并被拒绝。如果它失败并且不在trycatch块内,那么它将创建一个未处理的Promise Rejection。

TLDR:如果使用await关键字,则用try-catch将其包装起来。

此函数需要一个trycatch块

async function DoSomething() {
try {
const result = await MakeRequest(); // failure must be handled here
return result;
} catch (error) {
// Handle error
}
}

此函数不需要trycatch块

// This requires a trycatch block
async function DoSomething() {
return MakeRequest(); // failure can be handled by parent function
}

最新更新