我的PlayFramework Action在Future准备就绪之前返回,如何更新网页组件



我有一个调用MongoDB并获得Future[Seq[Document]]结果的Scala PlayFramework函数。 在地图缩放/平移事件之后,通过 xhttp/GET 从网页上的 JavaScript 调用此 Play Action 函数。 我在播放端的操作方法在执行未来onComplete/Success之前返回。 所以我正在寻找一种方法来调用JavaScript函数,以便在Scala Future的onComplete/Success触发时获取数据。 我该怎么做,还是我看错了?

这是有问题的代码。

def rect(swLon: Float, swLat: Float, neLon: Float, neLat: Float) = Action {
  val sb = new StringBuilder()
  sb.append("<tt>boundingBox: swLon=" + swLon + ", swLat=" + swLat + ", neLon=" + neLon + ", neLat=" + neLat + "</tt>")
  if (oDb.isDefined) {
    val collection: MongoCollection[Document] = oDb.get.getCollection(collectionName)
    val fut = getFutureOne(collection) // returns a Future[Seq[Document]]
    fut onComplete {
      case Success(docs) => { for (doc <- docs) { setMongoJson(doc.toJson } }
      case Failure(t) => { println("FAIL: " + t.getMessage) }
    }
  }
  Ok(sb.toString)
}
// below is temporary until I figure out a better way to store/return the result when it comes in
private var mongoJson: String = ""
private def setMongoJson(s: String): Unit = mongoJson = s

getFutureOne是暂时的,它只是做了一个db.collection.find().first().toFuture。 我只是想确保我与MongoDB的连接正常工作,而且确实如此。 实际上,我将用查询替换它以返回位于边界框内的数据。

Action不是

为处理期货而设计的。使用 Action.async ,它将"等待"(技术上不是等待,而是计划)以等待将来完成:

def rect(swLon: Float, swLat: Float, neLon: Float, neLat: Float) = Action.async {
  val sb = new StringBuilder()
  sb.append("<tt>boundingBox: swLon=" + swLon + ", swLat=" + swLat + ", neLon=" + neLon + ", neLat=" + neLat + "</tt>")
  if (oDb.isDefined) {
    val collection: MongoCollection[Document] = oDb.get.getCollection(collectionName)
    val fut = getFutureOne(collection) // returns a Future[Seq[Document]]
    fut.map {docs => 
      setMongoJson(doc.toJson)
      Ok(sb.toString)
    } recover {
      case e => BadRequest("FAIL: " + e.getMessage)
    }
  } else Future.successful(Ok("Not defined"))
}

看看这个作为参考:https://www.playframework.com/documentation/2.4.x/ScalaAsync

最新更新