0

我有一个网络请求的未来结果,我需要计算它的大小。如果当前响应有项目,我需要再次请求获取下一组,等等。如果当前响应为空,我就完成了。

我现在拥有的代码:

def list(prefix: String, lastItem: Option[String] = None, last: Seq[BucketItem] = Nil):  Future[Iterable[BucketItem]] = {
  Logger.debug(s"list :: prefix=$prefix, lastItem=$lastItem, lastItems=${last.size}")
  for {
    current <- s3.get(name, None, Some(prefix), delimiter, lastItem, None) map listResponse // type is Seq[BucketItem]
    next <- list(prefix, Some(current.last.name), last ++ current) if !(current.isEmpty)
  } yield last ++ current
}

这似乎工作正常,直到 current 没有更多元素,并且我得到 NoSuchElementException 试图获取 current.last.name

我理解如果 !(current.isEmpty) 扩展到过滤器的条件,所以这不是我真正想要的。我想要的是:

sequentially:
eval current
if current has more items, recursively call list to get the next set of items
yield the concatenated sequence of the right type (all the previous entries plus the last0

我在这里使用 for 理解来轻松处理收集期货(至少这是我过去的做法)。有什么指导/要读的东西吗?我对 scala 还很陌生,所以请温柔一点。

4

2 回答 2

0

我认为您的过滤器放错了位置,这应该可以:

def list(prefix: String, lastItem: Option[String] = None, last: Seq[BucketItem] = Nil):  Future[Iterable[BucketItem]] = {
  Logger.debug(s"list :: prefix=$prefix, lastItem=$lastItem, lastItems=${last.size}")
  for {
    current <- s3.get(name, None, Some(prefix), delimiter, lastItem, None) map listResponse // type is Seq[BucketItem]
    if !current.isEmpty
    next <- list(prefix, Some(current.last.name), last ++ current)
  } yield last ++ current
}
于 2014-04-23T01:20:25.500 回答
0

您不使用该变量next,因此您无法s3.get在第一次调用之后获得调用结果。此外,您if !(current.isEmpty)将调用withFilter一个Future值,这可能会产生一个 failed Future,这不是您想要的。

这是一个更简单的解决方案:

def list(prefix: String, lastItem: Option[String] = None, accum: Seq[BucketItem] = Vector()):  Future[Iterable[BucketItem]] = {
  s3.get(name, None, Some(prefix), delimiter, lastItem, None) flatMap { current =>
    if (current.isEmpty)
      Future.successful(accum)
    else
      list(prefix, bucketItems.last.name, accum ++ current)
  }
}

for-comprehension 只能表示map嵌套的flatMap调用内部(或foreach彼此内部的调用),其中散布调用withFilter. 我们在这里只需要一次调用flatMap,所以没有用 for for

我也替换ListVector, 将元素附加到末尾时效果更好。

于 2014-04-23T01:36:21.843 回答