我有两个功能,控制器和服务。这是服务代码。
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
,要么拒绝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
我建议您保持原样。不需要在不同的地方添加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
}