Real World Example

Search-as-you-type with a Timeout

In a shopping app search box, each new letter cancels the previous search, and a slow search falls back to cached suggestions after 300 ms.

type "s"   → search("s")     ✗ cancelled by next key
type "sh"  → search("sh")    ✗ cancelled by next key
type "sho" → search("sho")   ✓ finishes (or cache after 300 ms)

Code

Example

import kotlinx.coroutines.*

val cache = mapOf("shoe" to listOf("shoes (cached)", "shoe rack (cached)"))

suspend fun searchApi(query: String): List<String> {
    delay(if (query == "shoe") 800 else 200)     // "shoe" is slow today
    return listOf("$query for men", "$query for women")
}

class SearchBox(private val scope: CoroutineScope) {
    private var current: Job? = null

    fun onTextChanged(query: String) {
        current?.cancel()                           // drop the old search
        current = scope.launch {
            try {
                val results = withTimeoutOrNull(300) { searchApi(query) }
                    ?: cache[query].orEmpty()
                println("'$query' -> $results")
            } catch (e: CancellationException) {
                println("'$query' cancelled")
                throw e
            }
        }
    }

    suspend fun idle() { current?.join() }
}

fun main() = runBlocking {
    val box = SearchBox(this)
    box.onTextChanged("sh"); delay(50)
    box.onTextChanged("sho"); delay(50)
    box.onTextChanged("shir"); box.idle()
    box.onTextChanged("shoe"); box.idle()
}

Output

'sh' cancelled
'sho' cancelled
'shir' -> [shir for men, shir for women]
'shoe' -> [shoes (cached), shoe rack (cached)]