我正在试图找到一种编程函数的方法,这样它就能够处理不同的promise链路而不会重复代码。
通过一个具体的例子,我将详细阐述这个问题。
我有一个简单的API来更新用户的个人资料。它需要作为参数,新电子邮件或新用户名,或两者兼而有之。如果提供了用户名,我想验证是否未使用名为getExistingUser(username)
的函数来返回一个解析为实际用户数据的promise
。因此,代码片段就像
if (body.newUserName) {
getExistingUser(newUserName).then((existingUser) => {
if (existingUser) // return bad request error
else sql.update(newInfo) // an object that contains username (and email)
})
} else {
sql.update(newInfo) // an object that contains new email only
}
现在的挑战是,如果提供了用户名,则对用户配置文件的更新必须进入getExistingUser().then()
。但是,如果仅提供电子邮件,则完全相同的代码blob更新sql 将必须追踪getExistingUser
,从而导致代码重复。是否有一种构建器方法可以让我决定将哪些承诺链接起来,以便可以避免这种代码重复?
答案 0 :(得分:1)
对于像这样的情况,我个人更喜欢创建一个promisified验证函数,以保持我的承诺链完整,防止代码重复,例如
function saveUser(params) {
return validateRequest(params)
.then(function(validatedParams) {
db.updateUser(validatedParams)
})
}
function validateRequest(params) {
if(!params.email && !params.username) return {}
var parsedParams = {}
var promises = []
if(params.email) {
parsedParams.email = params.email
promises.push(getUserByEmail(parsedParams.email))
}
if(params.username) {
parsedParams.username = params.username
promises.push(getUserByUsername(parsedParams.username))
}
return Promise.all(promises).then(function(results) {
if(results.length > 0) {
throw new Error("Username or email already exists")
} else {
return parsedParams
}
})
}
答案 1 :(得分:0)
你似乎在寻找
(body.newUserName
? getExistingUser(newUserName).then(existingUser => {
if (existingUser) throw new Error("400 Bad request");
// else return undefined
})
: Promise.resolve(/* undefined */)
).then(() => {
return sql.update(newInfo)
}, err => {
// do something with the bad request errors
})
使用async
/ await
:
if (body.newUserName) {
const existingUser = await getExistingUser(newUserName);
if (existingUser) {
throw …; // or return
}
}
await sql.update(newInfo);
答案 2 :(得分:-1)
您可以尝试将所有内容限定在匿名函数中,并将本地函数作为回调添加。
(function() {
getExistingUser(body.newUserName)
.then(processUser, showErrorMessage);
function processUser(user) {
}
function showErrorMessage() {
}
})();
当您的代码变得更复杂并且在调试时需要更多有用的堆栈跟踪时,这也很有用。
- 更新
我刚刚重新阅读了您的帖子,虽然我的解决方案并非完全符合您的要求,但根据您的目的修改它是微不足道的。这也使人们非常清楚预期会发生什么。如果找到用户,请做一件事,否则做其他事情。如果你需要在两个实例中做同样的事情,那么最明确的事情就是创建另一个函数并从两个方法中调用它。这不是重复代码。