【问题标题】:Scala Futures for-comprehension with a list of values带有值列表的 Scala Futures 用于理解
【发布时间】: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 }
        }
  }

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

【问题讨论】:

    标签: scala async-await future for-comprehension


    【解决方案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,这将等待所有异步操作完成(或失败)。

    【讨论】:

      猜你喜欢
      • 2017-03-27
      • 2016-04-05
      • 2012-02-19
      • 1970-01-01
      • 2014-02-24
      • 1970-01-01
      • 2015-02-19
      • 2013-07-24
      • 2021-08-10
      相关资源
      最近更新 更多