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]],您可以通过 maping 由 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 和 flatMaps,直到最终有人知道如何处理结果。