2015-02-07 2 views
2

Я пробовал ScalaJS, но я застрял в этой глупой проблеме. Я пытаюсь создать некий «уровень доступа к данным», который использует REST-службу для извлечения некоторых данных.Ajax call отвечает пустым списком в ScalaJS

В этой службе я беру данные в JSON и преобразую их в Seq класса case и возвращаю их. Я протестировал несколько методов, я уверен, что данные получены правильно, потому что мне удалось получить их в браузере. Но при преобразовании его в 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 
    ) 
    } 
} 

ответ

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 
    } 
    } 

Конечно, затем до вызывающей fetchLatest() (которые вы не показывают здесь) в иметь дело с будущим, либо используя onComplete, либо преобразовывая его далее через map и flatMap, пока, в конце концов, кто-то не знает, что делать с результатом.

Смежные вопросы