【问题标题】:Deal with futures in a loop循环处理期货
【发布时间】:2015-08-01 12:41:25
【问题描述】:

我正在研究一种对数据库进行查询并占用一行的方法。此行有一列指定父 ID(如果有)。因此,我的方法有一个名为“迭代”的闭包,如果最后一行有父对象,则该闭包执行相同的过程,最后该方法返回这些行的序列。乍一看这很简单,但我必须处理期货之类的东西,而且我对异步编程没有太多经验。所以。我的问题是:

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

/**
   * 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 然后将其转换为序列来修复它。

【问题讨论】:

    标签: scala asynchronous concurrency slick slick-3.0


    【解决方案1】:

    我看到的一个问题是:parentsSeq +: Seq(parent)。这不会改变序列,而是返回一个新序列。

    【讨论】:

    • 我知道。但这不是我认为的主要问题。例如,我可以尝试使用 ListBuffer,但问题是,如果我在 clojure 之外定义变量以进行异步进程,那么该变量将来不存在,对吧?
    • 我不确定,但如果您使用可变集合或 var 并重新分配给它,我认为代码可以工作。根据定义,未来是尚不存在的东西......当执行 onComplete 回调时,我认为更新的集合应该可用。这个闭包有一个对集合的引用,当期货完成时它会被更新。
    • 你是对的。问题在于收藏。我一直在想这个问题是由期货引起的。无论如何...谢谢!
    • 不客气。顺便说一句,我认为您也可以映射动作本身。因此,您可以创建一系列动作(query.result 是一个动作),您可以递归地构建这些动作,类似于您对期货所做的事情,然后为它们创建一个动作 DBIO.sequence(actions) 并使用 db.run() 运行它,然后你会得到一个带有一系列结果的未来。
    • 问题是我需要之前的结果来检查是否需要继续查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2020-01-30
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多