如何处理依赖于先前结果的未知数量的期货?

时间:2016-05-17 17:08:29

标签: scala

我有一个方法可以进行API调用并返回Future[Seq[Post]],每个帖子都有一个序列id。 API调用每次调用返回200个帖子。为了获得完整的帖子序列,我在后续调用中提交最小的id(作为maxId)。每个Post对象还包含一个User对象,其中包含一个字段,指定用户发布的帖子总数。什么是以非阻塞方式完成所有用户帖子的最佳方式?

到目前为止,我有以下阻止代码:

def completeTimeline(userId: Long) = {
  def getTimeline(maxId = Option[Long] = None): Seq[Post] = {
    val timeline: Future[Seq[Post]] = userPosts(userId) // calls method that returns Future[Seq[Post]]
    Await.result(timeline, 5.seconds)
}

  def recurseTimeline(timeline: Seq[Post]): Seq[Post] = {
    if (timeline.length < timeline.head.user.map(user => user.post_count).getOrElse(0)) {
      val maxId = timeline.min(Ordering.by((p: Post) => p.id)).id - 1 // API call with maxId is inclusive, subtract 1 to avoid duplicates
      val nextTimeline = getTimeline(maxId = Some(maxId))
      val newTimeline = timeline ++ nextTimeline
      recurseTimeline(newTimeline)
    } else timeline
  }
  recurseTimeline(getTimeline())
}

2 个答案:

答案 0 :(得分:4)

这样的事情:

def completeTimeline(userId: Long): Future[Seq[Post]] = {

  def getTimeline(maxId: Option[Long] = None): Future[Seq[Post]] = {
    val timeline: Future[Seq[Post]] = userPosts(userId) // calls method that returns Future[Seq[Post]]
    timeline
  }

  def recurseTimeline(timeline: Seq[Post]): Future[Seq[Post]] = {
    if (timeline.length < timeline.head.user.map(user => user.post_count).getOrElse(0)) {
      val maxId = timeline.min(Ordering.by((p: Post) => p.id)).id - 1 // API call with maxId is inclusive, subtract 1 to avoid duplicates
      for {
        nextTimeline <- getTimeline(maxId = Some(maxId))
        full <- recurseTimeline(timeline ++ nextTimeline)
      } yield full
    } else Future.successful(timeline)
  }

  getTimeline() flatMap recurseTimeline
}

基本上,你是调度每个未来完成后发生的事情(map,flatMap和for-comprehension),而不是等待它们完成。

如果我对你想要做的事情有所了解,那么代码可能会被简化。

答案 1 :(得分:1)

当您说non-blockingI need to check all of the Posts不兼容时:您需要等待所有期货完成 - 从而能够在继续之前找到最低id。正确?或者您想进一步解释您的意图吗?

继续这个假设 - 您可以将每个Future添加到列表中,然后在列表上进行迭代并在每个列表上调用Await。这实际上是获得一套期货的标准阻止机制。

如果有进一步的考虑和/或假设,那么请提供它们 - 允许为您的详细信息调整这种一般方法。