首页 > 解决方案 > 将 Scala List[Either] 评估为布尔值

问题描述

我正在使用 scanamo 查询 dynamodb,我要做的就是检查 db 是否确实存在。我并不真正关心我得到的记录,只是没有错误。对于查询部分,我正在使用这个:

trait DynamoTestTrait extends AbstractDynamoConfig {  def test(): Future[List[Either[DynamoReadError, T]]] =    ScanamoAsync.exec(client)table.consistently.limit(1).scan())}

返回未来列表。我要评价第一个?列表中的项目,如果不是读取错误,则返回 true。

我认为这会起作用,但它不会:

 val result = test() match {
      case r: DynamoReadError => Future.successful(false)
      case r: Registration    => Future.successful(true)
    }

我是 scala 的新手,所以在返回类型和事情上苦苦挣扎。这是一个 Play api 调用,所以我需要在某个时候评估那个布尔未来。像这样:

 def health = Action {
    val isHealthy = h.testDynamo()
    val b: Boolean = Await.result(isHealthy, scala.concurrent.duration.Duration(5, "seconds"))
    Ok(Json.toJson(TestResponse(b.toString)))
  }

我认为这也可能是错误的,因为我不想使用 Await 但我也无法异步工作。对不起,我有点迷路了。

当我尝试评估结果时,我只会收到有关未来的消息:

{
"status": 500,
"message": "Future(<not completed>) (of class scala.concurrent.impl.Promise$DefaultPromise)"
}

标签: scalaplayframework

解决方案


结果是 aFuture所以你不能不做类似的事情来测试结果Await.result(就像你以后做的那样)。您可以做的是将返回的结果修改为Future您需要的结果。

在您的情况下,您可以这样做:

test().map(_.headOption.forall(_.isRight))

这将返回Future[Boolean],然后您可以在Await.result通话中使用它。

下面是它的工作原理:

  • map在 的结果上调用一个函数Future,它是 typeList[Either[DynamoReadError, T]]并返回一个 newFuture给出该函数调用的结果。

  • _.headOption获取列表的头部并返回一个Option[Either[DynamoReadError, T]]. 这是Some(...)如果列表中有一个或多个元素,或者None列表为空。

  • forall检查 的内容 Option并返回对该选项的测试结果。如果OptionNone则返回true

  • _.isRight测试该值Either[...]并返回true该值是否为Right[...]以及false是否为Left[...]

这符合您的要求,但也许最好检查是否有任何结果失败,而不仅仅是第一个结果?如果是这样,它实际上有点简单:

test().map(_.forall(_.isRight))

这将检查 a 中的所有条目ListRight并在找到 a 时立即失败Left

从这里返回的问题Play是一个单独的问题,可能应该在一个单独的问题中。


推荐阅读