Ausgabe
Ich habe diesen Beispielcode unten. Ich möchte den inneren Kombinator nicht blockieren resource.map
, also füge ich ihn ein . Aber wenn ich diese asynchrone Rekursion teste, bekomme ich von . Was ist das Problem mit dem Code? Wie kann ich es beheben? Vielen Dank.Await.result
Future
concurrent.TimeoutException
myRes
// Code start here
val responses = Future.sequence(resource.map(params => asyncRecursionFunc(params)))
Await.result(responses, 5.minutes)
// My async function
def asyncRecursionFunc(params: sampleParameters, maxTryTimes: Int = 2, awaitTime: Int = 1): Future[(Seq[sample], String)] = {
val res: Future[GraphQLCluent.GraphQLResponse[SearchQueryResponse]] = client.query("gql", params).result
Future {
val myRes: GraphQLCluent.GraphQLResponse[SearchQueryResponse] = Await.result(res, 2.minutes)
val myValue: Seq[sample] = myRes.right.toSeq.flatmap(res => res)
if( !myValue.isEmpty || maxTryTimes <= 0 ){
(myValue, "stringMessage")
}
else{
Await.result(asyncRecursionFunc(params, maxTryTimes - 1, awaitTime + 1), (2*(awaitTime + 1)).minutes)
}
}
}
Lösung
Ja, du solltest verwenden flatMap
.
Await
ist sogar drinnen schlechtFuture
(in gewisser Weise ist es eigentlich schlimmer ). Es ist wahrscheinlich, was auch Ihr unmittelbares Problem verursacht (die ersten Abfragen erschöpfen alle Threads im Pool und Await
blockieren dann für immer).
Versuchen Sie es auf wirklich asynchrone Weise:
def doQuery(params: Foo, maxTries: Int) = client.query("gql", params).result.flatMap {
case Right(r) if r.nonEmpty => Future.successful(r -> "stringmessage")
case _ if maxTries == 1 => Future.successful(Nil -> "stringmessage")
case _ => doQuery(params, maxTries-1)
}
Beantwortet von – Dima
Antwort geprüft von – Jay B. (FixError Admin)