当前位置: 首页 > 知识库问答 >
问题:

如何在多个未来等待中检索部分结果,当某些可能超时?

宋高扬
2023-03-14

我在scala on play框架中使用FUTURE。但我很难在合并多个期货时出现超时的情况下获得部分最终结果。下面是我的代码的功能。它有两个未来分别查询两个提供者。然后使用for/yield语句合并结果。然后等待具有超时值的结果。当两个提供者按时回复查询时,它可以正常工作。但是,如果只有一个提供者按时回复,我知道等待将超时,但在这种情况下,我仍然需要检索从另一个按时回复的提供者返回的数据。我该怎么做?

val pool = Executors.newCachedThreadPool()
implicit val ec = ExecutionContext.fromExecutorService(pool)

var future1 = Future(QueryProvider(provider1, request1))  
var future2 = Future(QueryProvider(provider2, request2))  

val future = for {
    result1 <- future1
    result2 <- future2
 } yield (Merge(result1, result2))

 val duration = Duration(60000, MILLISECONDS)

 try{
     result = Await.result(future, duration).asInstanceOf[string]       
 }

catch{
    case _: Exception => println("time out...") 
    //Here how can I retrieve provider1's result if only provider2 timeout???***
 }

共有1个答案

伊裕
2023-03-14

您可以在akka中的之后使用而不是阻塞Await.result

val timeout =
  akka.pattern.after(FiniteDuration(60000, MILLISECONDS), using = system.scheduler){
    Future.successful(None)
  }

val resFuture = for {
    result1 <- Future firstCompletedOf Seq(future1.map{Some(_)}, timeout)
    result2 <- Future firstCompletedOf Seq(future2.map{Some(_)}, timeout)
} yield (result1, result2)

val result = resFuture map {
  case (Some(r1), Some(r2)) => Merge(r1, r2)
  case (Some(r1), None) => PartialResult1(r1)
  case (None, Some(r2)) => PartialResult2(r2)
  case _ => EmptyResult
}

在这种情况下,resFuture将在60秒内完成,您可以处理部分结果。此外,您不需要在播放中等待,也可以使用异步

如果你有许多相同类型的等价期货,你可以这样使用它:

val futures: Seq[Future[Int]] = ???
val futureWithTimeout =
  futures.map{ f => Future firstCompletedOf Seq(f.map{Some(_)}, timeout) }

val result: Future[Seq[Option[Int]]] = Future.sequence(futureWithTimeout)

// In case you need to know index of completed or not completed future
val indexedResults = result.zipWithIndex

// In case you just need only completed results
val completedResults: Future[Seq[Option[Int]]] = result.map{_.flatten}

这里的类型只是为了说明。

 类似资料:
  • 我想运行相同类型的任务(工作线程),但一次不超过一定数量的任务。当任务完成时,其结果是新任务的输入,然后可以启动该任务。 有没有好的方法可以在C 11中使用异步/未来范式来实现这一点? 乍一看,它看起来很简单,你只是生成多个任务: 然后,运行以获取任务的异步结果。 然而,这里的问题是,未来的对象必须存储在某种队列中并一个接一个地等待。但是,可以一遍又一遍地迭代未来的对象,检查它们中的任何一个是否准

  • 问题内容: 我正在寻找一种方法来异步执行go中的两个函数,该函数返回不同的结果和错误,等待它们完成并打印两个结果。另外,如果一个函数返回错误,我不想等待另一个函数,只打印错误。例如,我具有以下功能: 这里https://play.golang.org/p/-8StYapmlg是我是如何实现它,但是它有太多的代码,我想。可以通过使用interface {}来简化它,但是我不想这样。我想要更简单的东西

  • 我有一个应用程序,通过点击按钮(该数字被定义)用户创建任务(可调用)做一些计算。我希望任务完成时能够做出反应。使用Future.get()阻止应用程序。有什么方法可以在Callable返回结果时做出反应吗?

  • 问题内容: 我有一列datetime类型,我只想从中检索日期。反正有这样做吗? 以前它是一个纪元值,我将其转换为datetime。 这是一个示例结果: 我尝试了以下命令,但结果为负/零 问题答案: 您可以使用DATE函数。 例子 您只能通过strftime获得一天,

  • 我正在玩Firebase Storage烘烤成一个照片收集应用程序,收集照片并上传到Firebase Storage后端。我想上传多张照片并等待所有任务完成,收集下载URL并进行下一步。下面是我的代码 我希望收集所有的URI,并使用DownloadURI中存储的结果。当我输入这个时,我意识到这可能不是firebase的问题,而是理解如何等待并行任务完成,执行并继续处理结果。我怎样才能达到这个目标呢

  • 是否有一种方法可以在不阻塞事件循环的情况下等待一个未来完成? 我知道这个错误通常意味着什么,但我不知道在这种情况下...我试图在谷歌上搜索它,但没有找到任何关于将哪份清单放在哪里的明确解释。和以前一样,除非是强制性的,我更喜欢一次学一件事。 那么,回到这个问题:“基本”Vert.x是否有一种方法可以在事件循环不受干扰的情况下等待未来?