I want to display an image for 3 seconds while als...
# coroutines
s
I want to display an image for 3 seconds while also fetching, serializing and persisting a large JSON blob. Keeping in mind the whole operation could take more than 3 seconds on slow network, this is what I have right now
Copy code
viewmodelScope.launch {
      val deferredFetchAndPersist = async {
          some suspend fun()
      }
      val deferredTimer = async {
          delay(3000)
      }
      awaitAll(deferredFetchAndPersist, deferredTimer)

      hideImageView()
   }
This works but I feel it's a little too verbose. Is there a better way I can achieve this? Thanks
e
What if the operation takes less than 3 seconds? Right now you'd also await the timer for 3 seconds anyways. If that's not what you want, then cancel the timer on completion of the operation. And do you intend to show the image for more than 3 seconds if the operation takes more than that? Other than that this seems fine.
s
The requirement is to show the image for at least 3 seconds and yes for your 2nd question. If this seems fine then thanks!
u
looks fine to me. You could also use
coroutineScope { … }
and use
launch
instead of `async`and
awaitAll
Copy code
viewmodelScope.launch {
    coroutineScope {
      launch {
          fetchAndPersist()
      }
      launch {
          delay(3000)
      }
    }
    hideImageView()
   }
👍 1
Well, actually you should use launch if you don’t expect a result. When structured concurrency does not come handy you can also
joinAll
the `Job`s returned from
launch
instead of calling `awaitAll`on the `Deferred<Unit>`s
👍 1
b
another option would be to write it in sequential way, which is probably looks simpler in this particular case.
Copy code
delay(3000 - measureTimeMillis {
    yourSuspendFun()
})
hideImageView()
(delay works fine with negative arguments, so everything should work regardless if yourSuspendFun faster/slower than 3s)
👍 1
e
Wow, that's pretty effective and pretty difficult to understand as a reader! 👏 But that's arguable!
Maybe actually write it sequentially, on multiple lines and optionally with named values, to increase readability?
Copy code
val actualMillis = measureTimeMillis { yourSuspendFun() }
val minimumMillis = 3000
delay(minimumMillis - actualMillis)
hideImageView()
👍 1
s
I like it! Thanks for all the suggestions everyone 🙏