循环处理期货

时间:2015-08-01 12:41:26

标签: scala asynchronous concurrency slick slick-3.0

我正在研究一种对数据库进行查询并占用一行的方法。此行有一列指定父ID(如果有)。所以,我的方法有一个名为“iterate”的闭包,如果最后一行有一个父进程,那么它会执行相同的过程,最后该方法返回这些行的Sequence。这很简单,但我必须处理期货和那些东西,我对异步编程没有多少经验。所以。我的问题是:

有没有办法在不使用“等待”的情况下正确使用此方法?

/**
   * Returns all the parents of the given sector if any
   * @param childSector
   * @return
   */
  def getParents(childSector: ShopSector): Future[Option[Seq[ShopSector]]] = {
    val p = Promise[Option[Seq[ShopSector]]]
    val f: Future[Option[Seq[ShopSector]]] = p.future

    val parentsSeq: Seq[ShopSector] = Seq()

    f.onComplete( thing => println(s"Result from Iteration future: $thing") )

    def iterate(sector: ShopSector): Unit = {
      val query = for {
        c <- ShopSectors if c.id === sector.id
        p <- c.parent
      } yield p

      exists(sector.parent_id).map { exists =>
        if (exists) {
          db.run(query.result.head).map { parent =>
            println(s"Result parent: $parent")
            parentsSeq +: Seq(parent)
            iterate(parent)
          }
        } else {
          p success Option(parentsSeq)
        }
      }
    }

    iterate(childSector)

    f
  }

我顺便使用Slick。请注意,此方法效果不佳。它返回一个空的Seq,我知道很明显这会返回它。但印刷品工作正常并打印出正确的结果。事情是,我无法想象在所有期货完成之前有一个不会“消失”的变量的方法。

提前致谢。

编辑:好的伙计们。问题很简单。正如Ixx所说,parentsSeq集合并不可变。我使用ListBuffer修复它,然后将其转换为序列。

1 个答案:

答案 0 :(得分:0)

我看到的一个问题是:where date(date) between '2015-07-20' and '2015-07-30' 。这不会改变序列,而是返回一个新的序列。