首先,我不确定该主题是否属于 StackOverflow。但是,我发现了一些关于其他编程语言的讨论,这些讨论解决了 StackOverflow 上的主题,但不适用于 Javascript。所以,我只想把我的问题扔进戒指:
在 Javascript 中假设的 GetUserByUsername 函数中处理可能的“未找到”场景的最佳方式/模式是什么。
我为什么要问?我想在整个项目中遵循某种编码标准。
我更具体的情况如下:
- 我有班级用户
- 我有一个用户列表,其中包含用户类的实例
- 我查找某个用户,但该用户在列表中不存在
我应该如何处理我的相关功能中的“找不到”情况?
我发现了以下方法:
- 返回未定义
- RORO(接收对象,返回对象)
- 空对象模式
- 抛出自定义错误
那我到底是什么意思。以下面的示例类用户为例。
module.exports = class User {
constructor() {
this.userName = null,
this.name = null,
this.age = null
}
...
getName() {
console.log(this.name);
}
}
在我的代码中的某处,我有一个函数,它提供了从用户列表中按用户名返回某个用户的功能。该列表是一个数组,由 User 类的实例组成。
一个简单的实现可能是这样的:
{
...
getUserByUsername(pUserName) {
/* listOfUsers array with objects of the class User */
var lUser = this.listOfUsers.find(user => user.userName === pUserName);
return lUser;
}
...
}
在某些情况下,传递的用户名可能不属于某个用户。因此找不到用户。
我怎么能处理它?
1.)返回未定义 - 就像示例代码一样。
/* We expect "Unknown" is not a user name in that list*/
var lRequestedUser = getUserByUsername("Unknown");
/* Check if requested user is undefined. Note: I'm using lodash for staff like that */
if(_.undefined(lRequestedUser)) {
//Handling
}
lRequestedUser.getName();
2.)RORO(接收一个对象,返回一个对象)我将一个对象传递给我的函数,并返回一个对象作为结果。在我要返回的对象中,我有一个指示器显示操作是否成功。
getUserByUsername(pParams) {
if(_.undefined(pParams.userName)) {
//Throw custom error
}
var lReturnObject = {
isSuccessfull: false,
data: null
}
/* listOfUsers array with objects of the class User */
var lUser = this.listOfUsers.find(user => user.userName === pParams.userName);
if(!(_.undefined(lUser))) {
lReturnObject.isSuccessfull = true;
lReturnObject.data = lUser
}
return lUser;
}
...
}
/*
Building a object which is passed to the function. Username is a member of that object
*/
var lRequest = {
userName: "Unknown"
}
/* We expect "Unknown" is not a user name in that list*/
var lRequestedUser = getUserByUsername(lRequest);
if(!(lRequestedUser.isSuccessfull)) {
//Handling
}
lRequestedUser.data.getName();
3.) 空对象模式 我不喜欢该解决方案的事实是,如果主类获得附加功能,我总是必须增强空对象的类。
module.exports = class NullUser {
constructor() {
this.userName = null,
this.name = null,
this.age = null
}
...
getName() {
console.log(this.name);
}
}
{
...
getUserByUsername(pUserName) {
/* listOfUsers array with objects of the class User */
var lUser = this.listOfUsers.find(user => user.userName === pUserName);
if(_.undefined(lUser)) {
return new NullUser();
}
return lUser;
}
...
}
/* We expect "Unknown" is not a user name in that list*/
var lRequestedUser = getUserByUsername("Unknown");
lRequestedUser.getName();
4.) 抛出自定义错误
{
...
getUserByUsername(pUserName) {
/* listOfUsers array with objects of the class User */
var lUser = this.listOfUsers.find(user => user.userName === pUserName);
if(_.undefined(lUser)) {
throw new CustomError(...);
}
return lUser;
}
...
}
/* We expect "Unknown" is not a user name in that list*/
try {
var lRequestedUser = getUserByUsername("Unknown");
lRequestedUser.getName();
} catch (e) {
if (e instanceof CustomError) {
//Handling
}
}
就我个人而言,我更喜欢返回包含指标的对象的选项,以及引发自定义错误的选项。该示例是同步的。在我的项目中,我也有异步代码。我正在为此使用承诺。
那么有什么想法是“最好的”解决方案或我应该喜欢的方式吗?