Created
November 1, 2018 07:13
-
-
Save vitoksmile/593edd05d0bd6b717c2a091e6371a91c to your computer and use it in GitHub Desktop.
Extension to Deferred to await values without need catch Exception
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlinx.coroutines.CancellationException | |
import kotlinx.coroutines.Deferred | |
import kotlinx.coroutines.Dispatchers | |
/** | |
* Coroutine dispatcher that is confined to the Main thread operating with UI objects | |
*/ | |
val UI = Dispatchers.Main | |
/** | |
* Background coroutine dispatcher | |
*/ | |
val BG = Dispatchers.IO | |
/** | |
* Await success value or null if was exception | |
*/ | |
suspend fun <T> Deferred<T>.value(): T? { | |
return try { | |
await() | |
} catch (ignored: Exception) { | |
null | |
} | |
} | |
/** | |
* Await pair of success value and error | |
*/ | |
suspend fun <T> Deferred<T>.values(): Pair<T?, Throwable?> { | |
return try { | |
await() to null | |
} catch (canceled: CancellationException) { | |
null to null | |
} catch (error: Exception) { | |
null to error | |
} | |
} | |
/** | |
* Example | |
*/ | |
class Loader { | |
fun load(): Job = GlobalScope.launch(UI) { | |
val body: Deferred<String> = getBody() | |
// The next code may throw exception | |
System.out.println(body.await()) | |
} | |
fun loadSafety(): Job = GlobalScope.launch(UI) { | |
val body: String = getBody().value() ?: return@launch | |
// The next code don't throw exception | |
System.out.println(body) | |
} | |
fun loadSafetyWithError(): Job = GlobalScope.launch(UI) { | |
val body: Pair<String?, Throwable?> = getBody().values() | |
val result: String? = body.first | |
val error: Throwable? = body.second | |
when { | |
result != null -> { | |
// The next code don't throw exception | |
System.out.println("Success: $result") | |
} | |
error != null -> { | |
// The next code don't throw exception | |
System.out.println("Error: $error") | |
} | |
} | |
} | |
/** | |
* Sample Deferred | |
*/ | |
private suspend fun getBody() = coroutineScope { | |
delay(1000) | |
async { | |
if (Random.nextBoolean()) { | |
javaClass.toString() | |
} else { | |
throw Exception("Something was wrong") | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment