我有点难以使它结构化。这是我想做的事情:
def checkResultAndFetchUser(result: WriteResult, encryptedEmail: String): Future[Either[ServiceError, User]] = Future {
if (result.code contains 11000)
Left(ServiceError("Email already exists"))
else if (result.hasErrors)
Left(ServiceError(result.writeErrors.map(_.errmsg).toString))
else
userByEmail(encryptedEmail).map(user =>
user
).recover {
case NonFatal(ex) => Left(ServiceError(ex.getMessage))
}
}
checkResultAndFetchUser(
await(userCollection.insert(encryptedUser)), encryptedUser.email
)
我期望checkResultAndFetchUser
返回a Future[Either[ServiceError, User]]
,但是我看到了以下编译器失败:
Error:(155, 28) type mismatch;
found : scala.concurrent.Future[Either[DBService.this.ServiceError,com.inland.model.User]]
required: Either[DBService.this.ServiceError,com.inland.model.User]
Error occurred in an application involving default arguments.
checkResultAndFetchUser(
^
Error:(150, 19) type mismatch;
found : scala.concurrent.Future[Either[DBService.this.ServiceError,com.inland.model.User]]
required: Either[DBService.this.ServiceError,com.inland.model.User]
).recover {
^
该userByEmail(encryptedEmail)
方法给了Future[Either[ServiceError, User]]
我预期的效果,但是问题出在哪里?
编辑:我找到了一个解决方案:
def checkResultAndFetchUser(result: WriteResult, encryptedEmail: String): Future[Either[ServiceError, User]] = {
if (result.code contains 11000)
Future(Left(ServiceError("Email already exists")))
else if (result.hasErrors)
Future(Left(ServiceError(result.writeErrors.map(_.errmsg).toString)))
else
userByEmail(encryptedEmail)
}
await(checkResultAndFetchUser(
await(userCollection.insert(encryptedUser)), encryptedUser.email
))
可以吗?我的意思是,该实现是安全的,因为我正在使用局部变量返回Future
!。
就可以产生预期结果的意义而言,您的代码是可以的。但是,正如@Łukasz在评论中提到的那样,这样做有点浪费。
原因是,每当您实例化这样的Future时,都会产生一个新任务,该任务需要在某个ExecutionContext上进行调度。通常,每当您只需要将已计算的结果包装在Future中时(或者如果计算速度非常快),最好使用Future.successful
这种方法以避免开销。
这是我修改checkResultAndFetchUser函数的方法:
def checkResultAndFetchUser(result: WriteResult, encryptedEmail: String): Future[Either[ServiceError, User]] = {
if (result.code contains 11000)
Future.successful(Left(ServiceError("Email already exists")))
else if (result.hasErrors)
Future.successful(Left(ServiceError(result.writeErrors.map(_.errmsg).toString)))
else
userByEmail(encryptedEmail)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句