How to await inside a crossinline lambda from a suspend function?

304 Views Asked by At

I am using KotlinX.html to emit HTML to an output stream (e.g. FileWriter in the next sample) and the resulting HTML view depends of asynchronous data from a CompletableFuture (e.g. cfArtist).

I want to immediately start emitting static HTML (i.e. <html><body><h1>Artist Info</h1>), then suspend until data is available and then proceed.

HTML builders of KotlinX.html API are inline functions with crossinline functions as parameter, thus I am not allowed to call await in corresponding lambdas (e.g. cfArtist.await()).

I do not want to await before start emitting HTML and do not want to create other coroutines either. Is there any way to await inside those crossinline lambdas?

suspend fun viewArtistInfo(fileName: String, cfArtist: CompletableFuture<Artist>) {
    // val artist = cfArtist.await() // Ok
    FileWriter(fileName).use {
        // val artist = cfArtist.await() // Ok
        it
            .appendHTML()
            .html {
                body {
                    h1 { +"Artist Info" }
                    val artist = cfArtist.await() // ERROR Suspension functions can be called only within coroutine body
                    p { +"From: ${artist.from}" }
                }
        }
    }
}
0

There are 0 best solutions below