2017-06-07 3 views
1

Je suis en train de diffuser Futures comme Html (en jeu à Scala 2.5.2) avec l'idée étant qu'ils rendent à l'écran lorsque le Futures complet. Donc, je diffuser un Source comme chaîne comme ceci:flux Html au navigateur lorsque Future termine

def oneFuture = Action { request => 
    val source1: Source[String, NotUsed] = fromFuture(sc.makeServiceCall("async1")) 
    Ok.chunked(source1) 
    } 

sc.makeServiceCall appels:

class ServiceClient @Inject() (ws: WSClient) { 

    def makeServiceCall(serviceName: String): Future[String] = { 
     ws.url(s"http://localhost:9000/mock/$serviceName").get().map(_.body) 
    } 

    } 

qui fait référence:

class Mock @Inject() (actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends Controller { 

    def mock(serviceName: String) = Action.async { request => 
     serviceName match { 
     case "async1" => respond("asy1", 1.second) 
     case "async2" => respond("asy2", 3.second) 
     } 
    } 

    private def respond(data: String, delay: FiniteDuration): Future[Result] = { 
     val promise: Promise[Result] = Promise[Result]() 
     actorSystem.scheduler.scheduleOnce(delay) { promise.success(Ok(data)) } 
     promise.future 
    } 

    } 

qui retourne asy1 après 1 seconde. Donc, dans cet esprit comment je devrais rendre Html dans le navigateur si je voulais diffuser une page de modèle, par exemple. views.html.async1.async1Message("a simple string") - qui est:

@(async1Message: String) 

    <span style="color: red; font-size: 22px; font-weight: bold;">@async1Message</span> 
+0

Qu'avez-vous encore essayé? Avez-vous mappé le résultat de l'appel de service dans le modèle, puis l'avez renvoyé? Cela semble être plus d'une question frontend, comment gérez-vous la réponse en javascript, non? Comment l'extrémité est-elle appelée? – thwiegan

Répondre

0

Pourquoi insistez-vous sur le streaming le résultat? Vous pouvez simplement renvoyer la page entière de manière asynchrone, c'est un petit modèle. Cela dit, si cela est à des fins d'apprentissage, vous devez savoir que Source.fromFuture crée une source Akka avec un élément unique. Vous devez le diviser en morceaux vous-même. Vous pouvez le faire comme ceci:

val chunkSize = 512 // 512 characters of your string 
val source = Source.fromFuture(sc.makeServiceCall("async1")) 
    .mapConcat(_.grouped(chunkSize)) 
Ok.chunked(source) 
+0

Oui - c'est pour l'apprentissage à ce stade. Je reçois un 'discordance de type; trouvé: Iterator [String] requis: scala.collection.immutable.Iterable [?] .mapConcat (_. grouped (chunkSize)) '. Supposons que 'sc.makeServiceCall (" async1 ")' est un _Future [Result] _ et (comme je le dis) je veux retourner _HTML markup_ –