我正在尝试ScalaJS,但我仍然坚持这个愚蠢的问题。我正在尝试构建一种使用REST服务来获取某些数据的“数据访问层”。
在这个服务中,我用JSON获取数据并将它们转换为case类的Seq并返回它们。我测试了几种方法,我确信数据是正确获取的,因为我已经设法将它传到浏览器中。但是当它转换为Seq时,Seq总是空的。
欢迎任何帮助......
object Results {
def fetchLatest(): Seq[Result] = {
var result = Seq.empty[Result]
get("http://tac-mlavaert.rhcloud.com/results/list/national/after_ss/latest").onComplete {
case Success(request: dom.XMLHttpRequest) =>
result = asList(request.responseText).map(ResultFactory.apply).toSeq
}
result
}
private def asList(response: String): js.Array[js.Dynamic] = js.JSON.parse(response) match {
case list: js.Array[js.Dynamic] => list
}
}
object ResultFactory {
def apply(item: js.Dynamic) = {
Result(
item.carNumber.toString,
item.pilotName.toString,
item.coPilotName.toString
)
}
}
答案 0 :(得分:3)
这是经典的使用 - 异步 - 功能 - 如果它是同步的问题的实例。您的fetchLatest()
方法首先声明一个空序列,然后调用get
,然后返回result
。但由于get
是异步的,fetchLatest()
在执行回调之前返回result
方式,这意味着返回您声明它时的空序列。 (最终回调运行并修改变量result
,但此时此人不再使用它。)
因此您无法直接返回结果fetchLatest()
。一旦进入异步世界,就不能离开它。这意味着您的fetchLatest()
方法还必须返回Future[Seq[Result]]
,您可以通过map
get
返回的未来获取该 def fetchLatest(): Future[Seq[Result]] = {
get("http://tac-mlavaert.rhcloud.com/results/list/national/after_ss/latest") map { request =>
asList(request.responseText).map(ResultFactory.apply).toSeq
}
}
。这看起来像这样:
def fetchLatest(): Future[Seq[Result]] = {
for {
request <- get("http://tac-mlavaert.rhcloud.com/results/list/national/after_ss/latest"
} yield {
asList(request.responseText).map(ResultFactory.apply).toSeq
}
}
或等效地,使用for-comprehension:
fetchLatest()
当然,使用onComplete
或通过{{1}进一步转换后,由map
(您未在此处显示)的来电者来处理未来} s和flatMap
s,直到最终有人知道如何处理结果。