Ajax 调用在 ScalaJS 中响应空列表
Ajax call responds empty list in ScalaJS
我正在试用 ScalaJS,但我被这个愚蠢的问题困住了。我正在尝试构建某种使用 REST 服务来获取一些数据的 'data access layer'。
在此服务中,我获取 JSON 中的数据并将它们转换为案例 class 和 return 的 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
)
}
}
这是典型的使用异步函数就好像它是同步问题的一个实例。您的 fetchLatest()
方法首先声明一个空序列,然后调用 get
,然后是 returns result
。但是由于 get
是异步的,fetchLatest()
returns result
在执行回调之前的方式,这意味着 returns 是空序列你宣布了它。 (最终回调运行并修改变量 result
,但此时已不再被任何人使用。)
所以你不能return直接导致fetchLatest()
。一旦进入异步世界,就无法离开。这意味着您的 fetchLatest()
方法还必须 return 一个 Future[Seq[Result]]
,您可以通过 map
ing 由 get
编辑的未来 return 来获得它。看起来像这样:
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
}
}
或等价地,使用 for-comprehension:
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
}
}
当然,接下来由 fetchLatest()
的调用者(此处未显示)来处理未来,要么使用 onComplete
,要么通过 [= 进一步转换它22=]s 和 flatMap
s,直到最终有人知道如何处理结果。
我正在试用 ScalaJS,但我被这个愚蠢的问题困住了。我正在尝试构建某种使用 REST 服务来获取一些数据的 'data access layer'。
在此服务中,我获取 JSON 中的数据并将它们转换为案例 class 和 return 的 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
)
}
}
这是典型的使用异步函数就好像它是同步问题的一个实例。您的 fetchLatest()
方法首先声明一个空序列,然后调用 get
,然后是 returns result
。但是由于 get
是异步的,fetchLatest()
returns result
在执行回调之前的方式,这意味着 returns 是空序列你宣布了它。 (最终回调运行并修改变量 result
,但此时已不再被任何人使用。)
所以你不能return直接导致fetchLatest()
。一旦进入异步世界,就无法离开。这意味着您的 fetchLatest()
方法还必须 return 一个 Future[Seq[Result]]
,您可以通过 map
ing 由 get
编辑的未来 return 来获得它。看起来像这样:
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
}
}
或等价地,使用 for-comprehension:
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
}
}
当然,接下来由 fetchLatest()
的调用者(此处未显示)来处理未来,要么使用 onComplete
,要么通过 [= 进一步转换它22=]s 和 flatMap
s,直到最终有人知道如何处理结果。