Scala проверяет, является ли Future[Seq[String]] пустым


Я хотел бы проверить, является ли будущее[Seq[String]] пустым, и я использую

if(!Future.sequence(sortSeq).isEmpty){
//doSomething
}

Но это бросает мне ошибку ?

2 2

2 ответа:

Я полагаю, что тип sortSeq - это Future[Seq[String]], поэтому вам не нужно Future.sequence.

Вы должны дождаться результата вашего Future , а затем проверить, пуст ли результат:

import scala.concurrent.duration._
if(!Await.result(sortSeq.map{_.isEmpty}, 5.seconds){
  //doSomething
}

Если вы можете выполнить doSomething в другом потоке, вы можете попробовать это:

val someRusultFuture = sortSeq.map{ rs =>
  if(!rs.isEmpty){
    //doSomething
  }
}

Но вам придется подождать результата someRusultFuture.

Доказательство того, что это работает:

scala> import concurrent.{Future, Await}
import concurrent.{Future, Await}

scala> import scala.concurrent.duration._
import scala.concurrent.duration._

scala> val sortSeq = Future{ Thread.sleep(10000); Seq("a") }
sortSeq: scala.concurrent.Future[Seq[String]] = scala.concurrent.impl.Promise$DefaultPromise@3592f7c6

scala> Await.result(sortSeq.map{_.isEmpty}, 11.seconds)
res1: Boolean = false

Future.sequence метод используется для преобразования TraversableOnce[Future[A]] в Future[TraversableOnce[A]].

Я думаю, что вы можете забыть, является ли Seq пустым или нет, и просто работать с Seq, используя функцию map Future

  val s = Future[Seq[String]](Seq("s", "e", "q"))
  val p  = s.map(s => s.foreach(println))

Это работает потому, что пустая проверка выполняется неявно в фоновом режиме. В приведенном ниже примере, когда Seq пусто, ничего не будет напечатано.

scala>   val s = Future[Seq[String]](Seq.empty)
s: scala.concurrent.Future[Seq[String]] = Future(<not completed>)

scala>   val p  = s.map(s => s.foreach(println))
p: scala.concurrent.Future[Unit] = Future(<not completed>)

Если Вы действительно хотите выполнить пустую проверку, вы можете также использовать withFilter.

С непустым Seq

scala>   val s = Future[Seq[String]](Seq("s", "e", "q"))
s: scala.concurrent.Future[Seq[String]] = Future(Success(List(s, e, q)))

scala>   val p  = s.withFilter(_.nonEmpty).map(s => s.foreach(println))
p: scala.concurrent.Future[Unit] = Future(<not completed>)

s
e
q

С пустым Seq

scala>   val s = Future[Seq[String]](Seq.empty)
s: scala.concurrent.Future[Seq[String]] = Future(Success(List()))

scala>   val p  = s.withFilter(_.nonEmpty).map(s => s.foreach(println))
p: scala.concurrent.Future[Unit] = Future(<not completed>)

Также вы можете сделать пустую проверку, как указано в приведенном выше ответе

val someRusultFuture = sortSeq.map{ rs =>
  if(!rs.isEmpty){
    //doSomething
  }
}

Надеюсь, это поможет.