I have a suspend function: ```private suspend fun ...
# coroutines
m
I have a suspend function:
Copy code
private suspend fun getThing(){...}
How can I set a minimum return time on this? So it will only return if at least 2000ms have passed, for example?
p
using a delay
m
literally just
delay(2000)
?
p
Rather this?
Copy code
suspend fun getThing() {
  val start = System.currentTimeMillis()

  doStuff()

  val elapsed = System.currentTimeMillis() - start
  delay(2000 - elapsed)
}
m
That’ll do it! Thanks a lot 🙂
Unless there’s a way to do it in fewer lines? I’m all ears 😄
c
Maybe something like
Copy code
delay(2000 - measureTimeMillis { doStuff() })
👌 1
🙌 1
p
Copy code
suspend fun getThing() : Int {
  return iWillReturnEarliestInTwoSeconds {
    doStuff()
  }
}

suspend inline fun <T> iWillReturnEarliestInTwoSeconds(action: () -> T): T {
  val start = System.currentTimeMillis()

  val result = action()

  val elapsed = System.currentTimeMillis() - start
  delay(2000 - elapsed)

  return result
}
m
very nice @Chris Miller. I think this
measureTimeMillis{}
is basically doing what you have written here @Paul Woitaschek?
c
Yes - have a look at the source code for it
👍 1
m
thanks both
p
That measure thing doesn't have a return value. Usually getThing indicates that there is a thing to get
m
yeah true but in my case getThing just updates a LiveData, it’s not returning a value 🙂
j
You have measureTimedValue for getting the elapsed time + the return value (if you need it some other time)
p
Here we go 😛
Copy code
suspend inline fun <T> iWillReturnEarliestInTwoSeconds(action: () -> T): T {
  val (result, elapsed) = measureTimedValue(action)
  delay(Duration.seconds(2) - elapsed)
  return result
}
👍 1
I can make it even more cryptic 🙈
Copy code
suspend inline fun <T> iWillReturnEarliestInTwoSeconds(action: () -> T): T = measureTimedValue(action)
  .also {
    delay(Duration.seconds(2) - it.duration)
  }.value
e
just launch a delay, due to how structured concurrency works you won't return until all children are done
Copy code
private suspend fun getThing() {
    launch { delay(2000) }
    // do other stuff
2
u
Not exactly. You need a scope
Copy code
private suspend fun getThing() = coroutineScooe {
    launch { delay(2000) }
    // do other stuff
}
👍 1
p
That is technically correct but probably I wouldn't write it as most of the devs wouldn't understand it
u
They better learn it 😉
Seriously scope is fundamental in coroutines. And waiting for it's children is a key feature of scopes. That's all this method is for.
2
But if you don't like it, feel free to just join launch's job. Might be a bit more expressive i agree
Copy code
private suspend fun getThing() {
    val delayJob = launch { delay(2000) }
    // do other stuff
    delayJob.join()
🙌 2