处理Scala中的Future [Ething]类型

乔山

我有点难以使它结构化。这是我想做的事情:

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Scala中,如何为Future [Option [A]]进行类型转换?

来自分类Dev

在Slick,scala中处理Postgres json数据类型

来自分类Dev

在 Scala 中动态处理任何数据类型

来自分类Dev

无法从多个不同类型的期货组成Scala Future的过程中

来自分类Dev

Scala类型不匹配找到Future [A]预期Future [B]

来自分类Dev

未处理的异常:类型'Future <dynamic>'不是类型'Future <alertDialogAction>'的子类型

来自分类Dev

Scala中的类型-下界

来自分类Dev

在scala中组合类型

来自分类Dev

Scala中的类型擦除

来自分类Dev

Scala中的类型-下界

来自分类Dev

Scala中的嵌套类型

来自分类Dev

Scala 中的链接类型

来自分类Dev

scala 中的结构类型

来自分类Dev

处理部分应用的函数时,Scala编译器中类型推断限制的原因

来自分类Dev

如何处理在Scala中返回具有泛型类型的对象的函数

来自分类Dev

Scala 如何处理方法返回类型中 Any 到 AnyVal 的协方差?

来自分类Dev

Scala:返回类型Seq [A]或Future [Seq [A]]的泛型

来自分类Dev

Scala:返回类型Seq [A]或Future [Seq [A]]的泛型

来自分类Dev

boost :: async()中boost :: future <>的类型

来自分类Dev

Scala 类型不匹配:发现 Future[MyType] 需要 Future[Option[MyType]]

来自分类Dev

Scala Future 失败场景的异常处理

来自分类Dev

与scala中的存在类型混淆

来自分类Dev

Scala:类型参数中的问号

来自分类Dev

Scala中的类型别名

来自分类Dev

Scala中的ADT子类型

来自分类Dev

在Scala中访问类型成员

来自分类Dev

Scala列表中的混合类型

来自分类Dev

Scala中类型类的性能

来自分类Dev

Scala中变量的打印类型