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

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

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

问题

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

import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

val c = Promise[Result]()
Future { c.success(Web(query)) }
Future { c.success(Image(query)) }
Future { c.success(Video(query)) }

val timeout = after(80.milliseconds)
var i = 0
while (i < 3) {
  Await.ready(c.future, timeout) foreach { result =>
    results = results :+ result
  }
  i += 1
}

这是一个可能的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

c := make(chan Result)
go func() { c &lt;- Web(query) } ()
go func() { c &lt;- Image(query) } ()
go func() { c &lt;- Video(query) } ()

timeout := time.After(80 * time.Millisecond)
for i := 0; i &lt; 3; i++ {
    select {
    case result := &lt;-c:
        results = append(results, result)
    case &lt;-timeout:
        fmt.Println(&quot;timed out&quot;)
        return
    }
}
return

答案1

得分: 0

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

// 假设Web/Image/Video函数返回Future[Result]的实例
val f1 = Web(query)
val f2 = Image(query)
val f3 = Video(query)
val t = timeout(80.milliseconds)

// 使用Scala的Future API
val results: Future[Seq[Result]] = for {
  r1 <- or(f1)(t)
  r2 <- or(f2)(t)
  r3 <- or(f3)(t)
} yield (r1.toSeq ++ r2.toSeq ++ r3.toSeq)

// 或者使用async
val results: Future[Seq[Result]] = async {
  val r1 = or(f1)(t)
  val r2 = or(f2)(t)
  val r3 = or(f3)(t)
  await(r1).toSeq ++ await(r2).toSeq ++ await(r3).toSeq
}

// or和timeout是下面定义的实用/库函数

def or[T](f1: Future[T])(f2: Future[Option[Nothing]]): Future[Option[T]] =
  Future.firstCompletedOf(f1 map Some.apply, f2)

// 创建一个在给定持续时间后成功完成为None的Future
def timeout(d: Duration): Future[Option[Nothing]] = {
  val p = Promise[Option[Nothing]]
  Scheduler.after(d) { p success None }
  p.future
}

希望这可以帮助到你!

英文:

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

// I assume that the Web/Image/Video functions return instances of Future[Result]
val f1 = Web(query)
val f2 = Image(query)
val f3 = Video(query)
val t = timeout(80.milliseconds)

// using Scala&#39;s Future API
val results: Future[Seq[Result]] = for {
  r1 &lt;- or(f1)(t)
  r2 &lt;- or(f2)(t)
  r3 &lt;- or(f3)(t)
} yield (r1.toSeq ++ r2.toSeq ++ r3.toSeq)

// OR using async
val results: Future[Seq[Result]] = async {
  val r1 = or(f1)(t)
  val r2 = or(f2)(t)
  val r3 = or(f3)(t)
  await(r1).toSeq ++ await(r2).toSeq ++ await(r3).toSeq
}

// or and timeout are utility/library functions defined below

def or[T](f1: Future[T])(f2: Future[Option[Nothing]]): Future[Option[T]] =
  Future.firstCompletedOf(f1 map Some.apply, f2)

// create a future that will complete successfully with None
// after the given duration passes
def timeout(d: Duration): Future[Option[Nothing]] = {
  val p = Promise[Option[Nothing]]
  Scheduler.after(d) { p success None }
  p.future
}

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:

确定