2016-07-13 7 views
0

In einer Play-scala Anwendung, Im einen WS Anruf:Benötigen Liste außerhalb der Karte in api Anruf spielt ws

def getaddresses : ListBuffer[String] = { 
    var lb = new ListBuffer[String]() 
    var url = "[email protected]/someapi" 

    WS.url(url).get.map { 
     response => 
     var emailsSeq = (response.json \\ "email") 
     emailsSeq.foreach(lb+=_.toString()) 
     lb.foreach(println)  //This is filled with values 
    } 
    lb.foreach(println)   //This is empty 
    lb 
} 

Innen Karte eine Sequenz zurückgegeben, deren Einträge ich in einem ListBuffer lb gestellt von zurückgegeben werden diese Methode. Das Problem ist, dass der ListBuffer Werte in der Karte {} zeigt, aber nicht außerhalb zeigt. Als Ergebnis wird ein leerer ListBuffer von der Methode übergeben.

ich dachte, es könnte eine Verzögerung in ws Antwort sein versucht, so die folgenden, die keinen Vorteil hatte:

WS.url(url).withRequestTimeout(10.seconds).get.map { 

Bitte helfen Sie mir gefüllt Listenpuffer immer

Antwort

0

ich, dass ws denken zurückgegeben werden. url (url) .get-Methode ist async, also wenn Sie lb.foreach (println) aufrufen, gibt es nichts zu drucken. Versuchen Sie, Thread.sleep unmittelbar nach dem Codeblock hinzuzufügen. Wenn dies der Fall ist, sollten Sie getaddresses async ausführen oder future/promise verwenden.

PS: Sie sollten val statt var verwenden, nur für saubereren Code.

EDIT: Probe, um zu versuchen:

def getaddresses : ListBuffer[String] = { 
    val url = "[email protected]/someapi" 

    val promiseOfAddresses = Promise[ListBuffer[String]]() 
    WS.url(url).get.map { 
     response => 
     var emailsSeq = (response.json \\ "email") 
     promiseOfAddresses.success(emailsSeq) // here you will complete promise with actual value 
    } 
    val lb = promiseOfAddresses.future.get // here you will obtain future from promise and also get value of future. Method get is blocking and it will wait till promise is fullfiled or failed 
    lb.foreach(println)   //This is empty 
    lb 
} 

PS2: Wahrscheinlich am besten hilft mit Zukunft/Versprechen sind hier zu finden: die-Neophyten-guide-to-scala-Teil-9-Versprechen-and-Futures -in der Praxis (Ich habe nicht genug Ruf, also googlen Sie diesen Blog) Es ist so etwas wie CompletableFuture in Java-Welt. Aber denken Sie daran, dass der beste Weg ist, die ganze Zeit auf der roten Seite zu bleiben (rot = asynchrone Funktionen/Methoden. Siehe schön, aber gesprächig, Blog what-color-is-your-function)

+0

danke für Ihre Antwort. lb.foreach (println) wird im Kartenblock gedruckt. Also denke ich, dass der Anruf nicht verzögert wird, aber wie bekomme ich diesen Wert außerhalb des Kartenblocks, um ihn an den Anrufer von getaddress weiterzuleiten. – surm

+0

Wie gesagt, Sie können versuchen, Zukunft zum Beispiel zu verwenden. Sehen Sie sich http://alvinalexander.com/scala/future-example-scala-cookbook-oncomplete-callback an oder versuchen Sie diesen einfachen Code, den ich meiner Antwort hinzufüge. –