如何一次又一次调用方法,直到它返回包含"None"的"Future"值

编程入门 行业动态 更新时间:2024-10-27 07:32:16
本文介绍了如何一次又一次调用方法,直到它返回包含"None"的"Future"值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

给出一个返回这样的Future的方法...

Given a method that returns a Future like this...

def remove(id: String): Future[Option[User]] = Future { // removes and returns the user identified by `id` }

...如何反复调用它,直到它返回包含None的Future值?

... how do I invoke it again and again until it returns a Future value containing None?

编辑

也许值得一提的是,我不需要收集结果.只要找到要删除的用户,我只需要调用该方法即可.想法是让loop在remove返回Future[None]时停止.

Perhaps it is worth to mention that I don't need to collect the results. I just need to invoke the method as long as it finds an user to remove. The idea would be to have a loop that stops when remove returns Future[None].

推荐答案

之前有人评论说没有意义.

Someone commented earlier that there's no point.

令我惊讶的是,没有懒惰地消费期货的快捷方式. Future.find类似于firstCompletedOf,并不表示find first in traversable order.

The surprise for me was that there's no quickie for lazily consuming the futures. Future.find is like firstCompletedOf, and doesn't mean find first in traversable order.

scala> import concurrent._, ExecutionContext.Implicits._ import concurrent._ import ExecutionContext.Implicits._ scala> import java.util.concurrent.atomic._ import java.util.concurrent.atomic._ scala> val count = new AtomicInteger(10) count: java.util.concurrent.atomic.AtomicInteger = 10 scala> def f(s: String) = Future { if (count.decrementAndGet <= 0) None else Some(s) } f: (s: String)scala.concurrent.Future[Option[String]] scala> def g(ss: List[String]): Future[List[String]] = f("hello") flatMap { case None => Future.successful(ss) case Some(s) => g(s :: ss) } g: (ss: List[String])scala.concurrent.Future[List[String]] scala> g(Nil) res0: scala.concurrent.Future[List[String]] = scala.concurrent.impl.Promise$DefaultPromise@65a15628 scala> .value res1: Option[scala.util.Try[List[String]]] = Some(Success(List(hello, hello, hello, hello, hello, hello, hello, hello, hello)))

说明不阻止的实用程序:

Illustrating the utility of not blocking:

scala> :pa // Entering paste mode (ctrl-D to finish) import scala.util._ import concurrent._, ExecutionContext.Implicits._ import java.util.concurrent.atomic._ class Work { val count = new AtomicInteger(10) def f(s: String) = Future { if (count.decrementAndGet <= 0) None else Some(s) } andThen { case Success(Some(x)) => Console println s"Calculated $x" case Success(None) => Console println "Done." case _ => Console println "Failed." } } // Exiting paste mode, now interpreting. import scala.util._ import concurrent._ import ExecutionContext.Implicits._ import java.util.concurrent.atomic._ defined class Work

显示Stream版本,直到消费线程逐步执行阻塞Awaits时,该版本才计算前缀:

Showing the Stream version, which won't calculate the prefix until the consuming thread steps through the blocking Awaits:

scala> val work = new Work work: Work = Work@1b45c0e scala> Stream continually work.f("hello") takeWhile { x => Await.result(x, duration.Duration.Inf).nonEmpty } Calculated hello res0: scala.collection.immutable.Stream[scala.concurrent.Future[Option[String]]] = Stream(scala.concurrent.impl.Promise$DefaultPromise@66629f63, ?) scala> .toList Calculated hello Calculated hello Calculated hello Calculated hello Calculated hello Calculated hello Calculated hello Calculated hello Done. res1: List[scala.concurrent.Future[Option[String]]] = List(scala.concurrent.impl.Promise$DefaultPromise@66629f63, scala.concurrent.impl.Promise$DefaultPromise@610db97e, scala.concurrent.impl.Promise$DefaultPromise@6f0628de, scala.concurrent.impl.Promise$DefaultPromise@3fabf088, scala.concurrent.impl.Promise$DefaultPromise@1e392345, scala.concurrent.impl.Promise$DefaultPromise@12f3afb5, scala.concurrent.impl.Promise$DefaultPromise@4ced35ed, scala.concurrent.impl.Promise$DefaultPromise@2c22a348, scala.concurrent.impl.Promise$DefaultPromise@7bd69e82) scala> .foreach (Console println _.value.get) Success(Some(hello)) Success(Some(hello)) [snip]

另一种可能更合乎需要的行为是,您将获得一个保存有计算前缀的结果的Future:

The other behavior, probably more desirable, where you get a Future that holds the result of calculating the prefix:

scala> :pa // Entering paste mode (ctrl-D to finish) val work = new Work def g(ss: List[String]): Future[List[String]] = work.f("hello") flatMap { case None => Future.successful(ss) case Some(s) => g(s :: ss) } // Exiting paste mode, now interpreting. work: Work = Work@796d3c9f g: (ss: List[String])scala.concurrent.Future[List[String]] scala> g(Nil) Calculated hello Calculated hello res3: scala.concurrent.Future[List[String]] = scala.concurrent.impl.Promise$DefaultPromise@99a78d7 Calculated hello Calculated hello Calculated hello scala> Calculated hello Calculated hello Calculated hello Calculated hello Done.

使用未来:

scala> .value res5: Option[scala.util.Try[List[String]]] = Some(Success(List(hello, hello, hello, hello, hello, hello, hello, hello, hello)))

更多推荐

如何一次又一次调用方法,直到它返回包含"None"的"Future"值

本文发布于:2023-11-27 23:56:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1640125.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:到它   方法   Future   quot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!