无法从多个不同类型的 Futures 组合 Scala Future
having trouble composing Scala Future from multiple Futures of different types
我有两个函数:一个 returns a Future[Thing Or Exception]
和另一个 returns Future[Boolean
。我想要一个同时调用 returns Future[Thing Or Exception]
的函数。如果布尔函数 returns false 我想 return 一个异常,否则 return 另一个函数。
我有这样的代码,但是 a) 我讨厌演员表和 b) 当 "boolean gets true" 路径上的 运行 时,当我最终 Await.result
在 return 在我的测试代码中:"Promise$DefaultPromise cannot be cast to org.scalatic.Or"
.
def thingFuture: Future[Thing Or Exception]
def boolFuture: Future[Boolean]
def combineFutures: Future[Thing Or Exception] = {
val result = boolFuture.map {x =>
x match {
case true => thingFuture
case false => Exception
}
}
// without the cast compiler says result is of type Future[Object]
result.asInstanceOf[Future[Thing Or Exception]]
}
我也试过了,但它在成功路径上得到了同样的 Promise 错误
def combineFutures: Future[Thing Or Exception] = {
val result = boolFuture.map {x =>
x match {
case true => thingFuture.map { y =>
y match {
case Good(thing) => thing
case Bad(exception) => exception
}
case false => Exception
}
}
}
谁能告诉我如何组合两个 return 类型的期货?谢谢!
如果发生异常,每个 future 都可以以失败状态完成,因此您可以简单地 return "happy path" 中的 thingFuture 并在 boolean 为 false 的情况下抛出异常。这将 return 一个具有基础异常的 Future.failed
。
val result = boolFuture.flatMap {x =>
x match {
case true => thingFuture
case false => throw new Exception("whatever")
}
}
请注意 flatMap
而不是 map
。因为我们将一个未来的潜在价值映射到另一个未来,通过使用简单的 map
我们最终会得到 Future[Future[Thing]]
.
另请注意,除了抛出异常外,您还可以 return 一个 Future.failed(throw new Exception("whatever"))
并且结果是相同的 - 在这两种情况下您都会遇到失败的未来。
编辑:我刚刚意识到 Or
来自 scalactic,我从未使用过它,但理念保持不变。你需要 flatMap 你的布尔未来和你的 ThingOrException
未来才能结束 Future[ThingOrException]
。如果你发现自己处于需要 flatMap 一个 Future 的情况,但其中一个 case 子句 return 是一个普通值(例如,如果是 true return Future[Thing]
,如果of false return just Exception
) 然后你可以将普通值包装到未来。这样所有分支 return 一个 future 和 flatMap 都会正常工作。例如:
val someOtherFuture = Future(43)
val someOrdinaryValue = 44
Future(someInteger).flatMap {
case 42 => someOtherFuture
case _ => Future(someOrdinaryValue)
}
为了稍微简化运行时机制,您也可以写成Future.successful(someOrdinaryValue)
,这样就不会启动后台计算。
据我从 Scalatic 文档中得知,您可以通过 Good(Right)
或 Bad(Left)
.
获得 Right Or Left
的实例
这意味着组合可能看起来像这样:
boolFuture.flatMap(b => if (b) thingFuture else Future.successful(Bad(new Exception())))
类型应统一为Future[Or[Thing, Exception]]
我有两个函数:一个 returns a Future[Thing Or Exception]
和另一个 returns Future[Boolean
。我想要一个同时调用 returns Future[Thing Or Exception]
的函数。如果布尔函数 returns false 我想 return 一个异常,否则 return 另一个函数。
我有这样的代码,但是 a) 我讨厌演员表和 b) 当 "boolean gets true" 路径上的 运行 时,当我最终 Await.result
在 return 在我的测试代码中:"Promise$DefaultPromise cannot be cast to org.scalatic.Or"
.
def thingFuture: Future[Thing Or Exception]
def boolFuture: Future[Boolean]
def combineFutures: Future[Thing Or Exception] = {
val result = boolFuture.map {x =>
x match {
case true => thingFuture
case false => Exception
}
}
// without the cast compiler says result is of type Future[Object]
result.asInstanceOf[Future[Thing Or Exception]]
}
我也试过了,但它在成功路径上得到了同样的 Promise 错误
def combineFutures: Future[Thing Or Exception] = {
val result = boolFuture.map {x =>
x match {
case true => thingFuture.map { y =>
y match {
case Good(thing) => thing
case Bad(exception) => exception
}
case false => Exception
}
}
}
谁能告诉我如何组合两个 return 类型的期货?谢谢!
如果发生异常,每个 future 都可以以失败状态完成,因此您可以简单地 return "happy path" 中的 thingFuture 并在 boolean 为 false 的情况下抛出异常。这将 return 一个具有基础异常的 Future.failed
。
val result = boolFuture.flatMap {x =>
x match {
case true => thingFuture
case false => throw new Exception("whatever")
}
}
请注意 flatMap
而不是 map
。因为我们将一个未来的潜在价值映射到另一个未来,通过使用简单的 map
我们最终会得到 Future[Future[Thing]]
.
另请注意,除了抛出异常外,您还可以 return 一个 Future.failed(throw new Exception("whatever"))
并且结果是相同的 - 在这两种情况下您都会遇到失败的未来。
编辑:我刚刚意识到 Or
来自 scalactic,我从未使用过它,但理念保持不变。你需要 flatMap 你的布尔未来和你的 ThingOrException
未来才能结束 Future[ThingOrException]
。如果你发现自己处于需要 flatMap 一个 Future 的情况,但其中一个 case 子句 return 是一个普通值(例如,如果是 true return Future[Thing]
,如果of false return just Exception
) 然后你可以将普通值包装到未来。这样所有分支 return 一个 future 和 flatMap 都会正常工作。例如:
val someOtherFuture = Future(43)
val someOrdinaryValue = 44
Future(someInteger).flatMap {
case 42 => someOtherFuture
case _ => Future(someOrdinaryValue)
}
为了稍微简化运行时机制,您也可以写成Future.successful(someOrdinaryValue)
,这样就不会启动后台计算。
据我从 Scalatic 文档中得知,您可以通过 Good(Right)
或 Bad(Left)
.
Right Or Left
的实例
这意味着组合可能看起来像这样:
boolFuture.flatMap(b => if (b) thingFuture else Future.successful(Bad(new Exception())))
类型应统一为Future[Or[Thing, Exception]]