你如何使用Scala的async来超时多个异步请求?

huangapple go评论125阅读模式
英文:

How would you time out multiple async requests with Scala's async?

问题

我不了解Scala,但我对它的异步特性(类似于C#)很感兴趣。你想要将这段Go代码翻译成Scala的异步代码,对吗?

  1. import scala.concurrent._
  2. import scala.concurrent.duration._
  3. import scala.concurrent.ExecutionContext.Implicits.global
  4. val c = Promise[Result]()
  5. Future { c.success(Web(query)) }
  6. Future { c.success(Image(query)) }
  7. Future { c.success(Video(query)) }
  8. val timeout = after(80.milliseconds)
  9. var i = 0
  10. while (i < 3) {
  11. Await.ready(c.future, timeout) foreach { result =>
  12. results = results :+ result
  13. }
  14. i += 1
  15. }

这是一个可能的Scala异步代码翻译。它使用了Scala的FuturePromise来实现异步操作,并使用Await.readyforeach来等待结果。请注意,这只是一种可能的翻译方式,具体实现可能因情况而异。

英文:

I don't know Scala but I am curious about its async feature (similar to C#'s). How would you translate this go code into Scala async?

http://talks.golang.org/2012/concurrency.slide#47

  1. c := make(chan Result)
  2. go func() { c &lt;- Web(query) } ()
  3. go func() { c &lt;- Image(query) } ()
  4. go func() { c &lt;- Video(query) } ()
  5. timeout := time.After(80 * time.Millisecond)
  6. for i := 0; i &lt; 3; i++ {
  7. select {
  8. case result := &lt;-c:
  9. results = append(results, result)
  10. case &lt;-timeout:
  11. fmt.Println(&quot;timed out&quot;)
  12. return
  13. }
  14. }
  15. return

答案1

得分: 0

这是一个可能的实现草图(未经测试;我不保证这是最佳解决方案):

  1. // 假设Web/Image/Video函数返回Future[Result]的实例
  2. val f1 = Web(query)
  3. val f2 = Image(query)
  4. val f3 = Video(query)
  5. val t = timeout(80.milliseconds)
  6. // 使用Scala的Future API
  7. val results: Future[Seq[Result]] = for {
  8. r1 <- or(f1)(t)
  9. r2 <- or(f2)(t)
  10. r3 <- or(f3)(t)
  11. } yield (r1.toSeq ++ r2.toSeq ++ r3.toSeq)
  12. // 或者使用async
  13. val results: Future[Seq[Result]] = async {
  14. val r1 = or(f1)(t)
  15. val r2 = or(f2)(t)
  16. val r3 = or(f3)(t)
  17. await(r1).toSeq ++ await(r2).toSeq ++ await(r3).toSeq
  18. }
  19. // or和timeout是下面定义的实用/库函数
  20. def or[T](f1: Future[T])(f2: Future[Option[Nothing]]): Future[Option[T]] =
  21. Future.firstCompletedOf(f1 map Some.apply, f2)
  22. // 创建一个在给定持续时间后成功完成为None的Future
  23. def timeout(d: Duration): Future[Option[Nothing]] = {
  24. val p = Promise[Option[Nothing]]
  25. Scheduler.after(d) { p success None }
  26. p.future
  27. }

希望这可以帮助到你!

英文:

Here's a sketch of how it could be done (untested; I make no claim that this is the best solution):

  1. // I assume that the Web/Image/Video functions return instances of Future[Result]
  2. val f1 = Web(query)
  3. val f2 = Image(query)
  4. val f3 = Video(query)
  5. val t = timeout(80.milliseconds)
  6. // using Scala&#39;s Future API
  7. val results: Future[Seq[Result]] = for {
  8. r1 &lt;- or(f1)(t)
  9. r2 &lt;- or(f2)(t)
  10. r3 &lt;- or(f3)(t)
  11. } yield (r1.toSeq ++ r2.toSeq ++ r3.toSeq)
  12. // OR using async
  13. val results: Future[Seq[Result]] = async {
  14. val r1 = or(f1)(t)
  15. val r2 = or(f2)(t)
  16. val r3 = or(f3)(t)
  17. await(r1).toSeq ++ await(r2).toSeq ++ await(r3).toSeq
  18. }
  19. // or and timeout are utility/library functions defined below
  20. def or[T](f1: Future[T])(f2: Future[Option[Nothing]]): Future[Option[T]] =
  21. Future.firstCompletedOf(f1 map Some.apply, f2)
  22. // create a future that will complete successfully with None
  23. // after the given duration passes
  24. def timeout(d: Duration): Future[Option[Nothing]] = {
  25. val p = Promise[Option[Nothing]]
  26. Scheduler.after(d) { p success None }
  27. p.future
  28. }

huangapple
  • 本文由 发表于 2014年4月5日 05:44:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/22873573.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定