【问题标题】:Evaluating a Scala List[Either] into a Boolean将 Scala List[Either] 评估为布尔值
【发布时间】:2018-12-20 01:27:14
【问题描述】:

我正在使用 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)"
}

【问题讨论】:

  • 结果是什么?我不完全确定您的数据库调用是如何工作的。但是您拥有的语法是结果将是案例中匹配的内容,然后返回到结果值中。所以它最有可能是真还是假?你能至少检查一下结果是什么吗?
  • 我似乎无法检查任何中间值是什么,因为它们是期货。不知道我该怎么做。
  • 阅读 Tim 的评论,您就会知道该怎么做。我忘了说结果是一个未来。要检查未来(结果),这就是你要做的 val futureResult = Await(result, 30 seconds); println(futureResult);但是蒂姆的解决方案更好,可以检查你所有的未来。如果你不了解左右.. 右基本上是试图检查它是否成功..那么那么是真的。并在它失败时离开。再次,检查蒂姆在下面的答案。

标签: scala playframework


【解决方案1】:

结果是Future,因此如果不执行Await.result 之类的操作(您稍后会这样做),您将无法测试结果。您可以做的是将Future返回的结果修改为您需要的结果。

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

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

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

这是它的工作原理:

  • mapFuture 的结果上调用一个函数,该结果是List[Either[DynamoReadError, T]] 类型,并返回一个新的Future,它给出了该函数调用的结果。

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

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

  • _.isRight 测试值Either[...],如果值为Right[...],则返回true,如果值为false,则返回false

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

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

这会检查List 中的所有条目是否为Right,并在找到Left 时立即失败。

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

【讨论】:

  • 我的想法是,如果我在 scanamo 调用中使用 limit(1),我将只能取回 1 或 0 条记录
  • 感谢您的帮助 - 这绝对可以满足我对 Future 结果的需求。现在我必须提出另外两个问题 - 一个是如何将 Play 响应作为异步处理,另一个问题是如果我将 dynamo 表的名称弄错了,那么它会失败,而不是在调用中返回 Left。跨度>
猜你喜欢
  • 2011-07-31
  • 2012-11-22
  • 1970-01-01
  • 2011-08-28
  • 2017-05-24
  • 2013-11-11
  • 1970-01-01
  • 2012-06-04
  • 2017-10-10
相关资源
最近更新 更多