trathschlag
11/11/2019, 9:53 AMlazy
? I'm not looking for async
. All I want is execution in the current coroutine, if the value was not yet computed.marstran
11/11/2019, 10:29 AMlazy
?trathschlag
11/11/2019, 10:53 AMval userToken = suspendableLazy {
getUserTokenFromServerWithPotentiallyLongIO()
}
val user = User(userToken.get())
....
val x = getXForUser(userToken.get())
jimn
11/11/2019, 12:21 PMbholota
11/11/2019, 12:24 PMDeferred
is all you need:
suspend fun currentTimeStamp(): Long {
delay(2000L) // simulate background operation
return System.currentTimeMillis()
}
@Test
fun lazyTest() = runBlocking {
val time = async {currentTimeStamp() }
println(time.await())
delay(2000L)
println(time.await())
}
second await will print same valuebholota
11/11/2019, 12:39 PMclass ScopePlayground : CoroutineScope {
private val job = SupervisorJob()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Default
private val time = async { currentTimeStamp() }
// rest of the code
trathschlag
11/11/2019, 1:34 PMCoroutineScope
is not available during definition time in my case. And I don't want to pass it on every invocation as it is basically unnecessary for what I want to achieve. I went with the following solution for now:
interface SuspendableProvider<T> {
suspend fun get(): T
}
fun <T : Any> suspendableLazy(provider: suspend () -> T) = object : SuspendableProvider<T> {
val mutex = Mutex()
lateinit var computed: T
override suspend fun get() = mutex.withLock {
if (!this::computed.isInitialized) {
computed = provider()
}
computed
}
}
jimn
11/11/2019, 1:36 PMtrathschlag
11/11/2019, 1:38 PM