Scala等待未来的清单执行

时间:2016-04-29 17:13:15

标签: scala akka scala-collections akka-stream

您好我正在尝试处理文件中的数据。

这是我在下面使用的代码。

我有一份期货清单,并试图从这些期货获得产量。

一切都很好,但最后一行返回在OnSuccess之前执行。

如何在不进行阻止操作的情况下更改该行为。

def processRow(rowNumber: Int, row: String, delimiter: String, rules: List[Rule]): RowMessage = {
var cells = row.split(delimiter)
var passedRules = new ListBuffer[RuleResult]()
val failedRules = new ListBuffer[RuleResult]()
val rulesFuture = rules.map {
  i => Future {
    val cells = row.split(delimiter);
    //some processing....
  }
}
val f1 = Future.sequence(rulesFuture)
f1 onComplete {
  case Success(results) => for (result <- results) (result.map(x => {
    if (x.isPassFailed) {
      passedRules += x
    }
    else {
      failedRules += x
    }
  }))
  case Failure(t) => println("An error has occured: " + t.getMessage)
}
return new RowMessage(passedRules.toList,   failedRules.toList)
}

1 个答案:

答案 0 :(得分:1)

您无法阻止并返回普通RowMessage。您还需要返回Future

def processRow(rowNumber: Int, row: String, delimiter: String, rules: List[Rule]): Future[RowMessage] = {
  val cells = row.split(delimiter)
  Future.traverse(rules) { i =>
    Future {
      //some processing....
    }
  } map { results =>
    val (passed, failed) = results.partition(_.isPassFailed)
    new RowMessage(passed, failed)
  }
}

还要考虑你的算法以避免可变状态,特别是当你从不同的Futures改变它时。

Future.traverse相当于您的map + Future.sequence。然后,只需映射Future以修改列表,而不是onComplete。您可以使用partition轻松拆分,而不是使用您正在进行的操作。

您不需要使用return,事实上除非您知道自己在做什么,否则不应该这样做。

顺便说一下isPassFailed对我来说听起来不是一个合理的方法名称,特别是考虑到它是正确的,你将它添加到通过的规则中。