我有以下方法对Future
s进行一些处理:
def registerNewUser(user: User): Future[Either[ServiceError, User]] = async {
val encryptedUser =
user.copy(encrypt(user))
def checkResultAndFetchUser(result: WriteResult, encryptedEmail: String): Future[Either[ServiceError, User]] = {
if (result.hasErrors)
Future.successful(Left(ServiceError(result.writeErrors.map(_.errmsg).toString)))
else
userByEmail(encryptedEmail)
}
def handleInsertError(result: WriteResult): Either[ServiceError, User] = {
if (result.code contains 11000)
Left(ServiceError("Email already exists"))
else
Left(ServiceError(result.writeErrors.map(_.errmsg).toString))
}
val result = userCollection.insert(encryptedUser).map( writeRes =>
checkResultAndFetchUser(writeRes, encryptedUser.email)
).recover {
case res: WriteResult => Future.successful(handleInsertError(res))
}
await(result.flatMap(fut => fut))
}
以下是我的问题:
encryptedUser
方法正在使用checkResultAndFetchUser
局部变量,userCollection.insert(encryptedUser)
会返回Future
,所以有可能是另一个encryptedUser
可能会在checkResultAndFetchUser
方法中捕获?那就意味着,我注定了!
这是处理Future
及其处理的好方法吗?
答案 0 :(得分:1)
我不确定你对第一个问题的意思,但只有一个encryptedUser
值,所以即使两个函数都返回Future
,它们都使用相同的encryptedUser
}。
为了处理你Future
s:
await
上使用Future
。您在map
上使用userCollection.insert()
,然后使用result.flatMap(fut => fut)
,可以将其简化为直接使用flatMap
。
userCollection.insert(encryptedUser).flatMap( writeRes =>
checkResultAndFetchUser(writeRes, encryptedUser.email)
)
也可以写成为理解。
最终结果可能如下:
def registerNewUser(user: User): Future[Either[ServiceError, User]] = {
def checkResultAndFetchUser(result: WriteResult, encryptedEmail: String) = ???
def handleInsertError(result: WriteResult) = ???
def insertUser(user: User): WriteResult =
userCollection.insert(user).recover {
case res: WriteResult => handleInsertError(res)
}
val encryptedUser = user.copy(encrypt(user))
for {
writeRes <- insertUser(encryptedUser)
user <- checkResultAndFetchUser(writeRes, encryptedUser.email)
} yield user
}