Scala Future用过滤器来理解

Mag*_*nus 23 scala future filter for-comprehension

在下面的示例中,我得到了例外 java.util.NoSuchElementException: Future.filter predicate is not satisfied

我想Future( Test2 )在检查if( i == 2 )失败时获得结果.我如何处理过滤器/如果处理组成期货的理解?

下面是一个在Scala REPL中工作的简化示例.

码:

import scala.concurrent.Future
import scala.util.{ Try, Success, Failure }
import scala.concurrent.ExecutionContext.Implicits.global

val f1 = Future( 1 )
val f2 = for {
  i <- f1
  if( i == 2 )
} yield "Test1"
f2.recover{ case _ => "Test2" }
f2.value
Run Code Online (Sandbox Code Playgroud)

pki*_*sky 31

在我看来,这是一个更惯用的解决方案.此谓词函数创建Future[Unit]包含异常的未来或失败的未来.对于您的示例,这将导致a Success("Test1")或a Failure(Exception("Test2")).这与"Test1"和"Test2"略有不同,但我发现这种语法更有用.

def predicate(condition: Boolean)(fail: Exception): Future[Unit] = 
    if (condition) Future( () ) else Future.failed(fail)
Run Code Online (Sandbox Code Playgroud)

你这样使用它:

val f2 = for {
  i <- f1
  _ <- predicate( i == 2 )(new Exception("Test2"))
  j <- f3  // f3 will only run if the predicate is true
} yield "Test1"
Run Code Online (Sandbox Code Playgroud)


tgr*_*tgr 12

在你的for-comprehension,你过滤i == 2.因为价值f1不是两个,它不会产生一个Success而是一个Failure.您的错误消息告诉您,过滤器的谓词不满足.但是,f2.recover返回一个新的Future.价值f2不受操纵.它仍然存储Failure.这就是你打电话时收到错误信息的原因f2.value.

我能想到的会是唯一的选择可以使用elsefor-comprehension如图所示这里.

val f2 = for ( i <- f1) yield {
  if (i == 2) "Test1"
  else "Test2"
}
f2.value
Run Code Online (Sandbox Code Playgroud)

这会Some(Success(Test2))像你f3.value一样回归.


Mag*_*nus 8

当然,我自己想出了一个解决方案.也许有更好,更惯用的解决方案?

import scala.concurrent.Future
import scala.util.{ Try, Success, Failure }
import scala.concurrent.ExecutionContext.Implicits.global

val f1 = Future( 1 )
val f2 = for {
  i <- f1
  if( i == 2 )
} yield "Test1"
val f3 = f2.recover{ case _ => "Test2"  }
// OR val f3 = f2.fallbackTo( Future( "Test2" ) )
f3.value
Run Code Online (Sandbox Code Playgroud)