I want to create an instance of a class in a suspe...
# coroutines
j
I want to create an instance of a class in a suspend function. I'm wondering if there's a better way to do this, since the way I'm doing it seems clunky. Typing this is slack so hopefully I don't mess up any syntax Example:
Copy code
class foo(
    var bar: String? = null,
    var baz: Int? = null,

    companion object {
        fun buildFoo(block: Foo.() -> Unit): Foo { // not suspending
            return Foo().apply { block() }
        }
    }
)

suspend fun newFoo(): Foo = coroutineScope {
    val bar = async { runDbQueryToGetBar() }
    val baz = async { runDbQueryToGetBaz() }

    // Send off the queries together and await them both
    val results = awaitAll(bar, baz) // List<Any> - awkward?

    buildFoo { // this: Foo
        this.bar = results[0] as String
        this.baz = results[1] as Int
    } // returns from coroutineScope
}
In my real-world usage, I need to cast to
Map<String, Int>
and it gives me an Unchecked Cast warning, which is just a little annoying.
k
Copy code
class foo(
    var bar: String? = null,
    var baz: Int? = null,

    companion object {
        fun buildFoo(block: Foo.() -> Unit): Foo { // not suspending
            return Foo().apply { block() }
        }
    }
)

suspend fun newFoo(): Foo = coroutineScope {
    val bar = async { runDbQueryToGetBar() }
    val baz = async { runDbQueryToGetBaz() }


    buildFoo { // this: Foo
        this.bar = bar.await()
        this.baz = baz.await()
    } // returns from coroutineScope
}
Your usage of awaitAll is probably pointless here so it's better just to await where you need the values.
2
a
If you made
buildFoo
an
inline
function, you would be able to suspend inside of the lambda without actually marking
buildFoo
as suspending
1
☝🏼 1
m
Can also just save the results outside
buildFoo
.