带有值列表的 Scala Futures 用于理解

Posted

技术标签:

【中文标题】带有值列表的 Scala Futures 用于理解【英文标题】:Scala Futures for-comprehension with a list of values 【发布时间】:2021-11-21 04:49:51 【问题描述】:

我需要同时对列表中的某些元素执行 Future 方法。我当前的实现是按顺序工作的,这对于节省时间并不是最佳的。我通过映射我的列表并在每个元素上调用方法并以这种方式处理数据来做到这一点。

我的经理与我分享了一个链接,展示了如何使用 for-comprehension 同时执行 Futures,但我无法看到/理解如何使用我的 List 来实现它。

他与我分享的链接是https://alvinalexander.com/scala/how-use-multiple-scala-futures-in-for-comprehension-loop/

这是我当前的代码:

private def method1(id: String): Tuple2[Boolean, List[MyObject]] = 
    val workers = List.concat(idleWorkers, activeWorkers.keys.toList)
    var ready = true;
    val workerStatus = workers.map worker =>
      val option =  Await.result(method2(worker), 1 seconds)
      var status = if (option.isDefined) 
        if (option.get._2 == id) 
          option.get._1.toString
         else 
          "INVALID"
        
       else "FAILED"
      val status = s"$worker: $status"
      if (option.get._1) 
        ready = false
      
      MyObject(worker.toString, status)
    .toList.filterNot(s => s. status.contains("INVALID"))
    (ready, workerStatus)
  

  private def method2(worker: ActorRef): Future[Option[(Boolean, String)]] = Future
      implicit val timeout: Timeout = 1 seconds;
      Try(Await.result(worker ? GetStatus, 1 seconds)) match 
            case Success(extractedVal) => extractedVal match 
                case res: (Boolean, String) => Some(res)
                case _ => None
            
            case Failure(_) =>  None 
            case _ =>  None 
        
  

如果有人可以建议如何在这种情况下实现理解,我将不胜感激。谢谢

【问题讨论】:

【参考方案1】:

对于method2,不需要Future/Await 混合。就mapFuture

def method2(worker: ActorRef): Future[Option[(Boolean, String)]] =
  (worker ? GetStatus).map
      case res: (Boolean, String) => Some(res)
      case _ => None
    

对于method1,你同样需要mapmethod2的结果,并在map内部进行处理。这将使workerStatus 成为List[Future[MyObject]],这意味着一切都并行运行。

然后使用Future.sequence(workerStatus)List[Future[MyObject]] 变成Future[List[MyObject]]。然后您可以再次使用mapList[MyObject] 进行过滤/检查。这将在所有个人 Futures 完成后发生。

理想情况下,您会从method1 返回一个Future,以保持一切异步。如果绝对必要,您可以在此时使用Await.result,这将等待所有异步操作完成(或失败)。

【讨论】:

以上是关于带有值列表的 Scala Futures 用于理解的主要内容,如果未能解决你的问题,请参考以下文章

Scala 中的异步 IO 与期货

转载:深入理解Scala的隐式转换系统

深入理解Scala的隐式转换系统

带有理解的Scala事务块

Scala中的隐式转换|理解

带有列列表的 Spark 选择 Scala