Котлин революционизирует асинхронное программирование. В версии 1.1 в языке появились корутины -- это свежий, отличных от других языков подход к проблеме написания асинхронного кода. Мы посмотрим на этот механизм как сверху -- чем он отличается от традиционных подходов таких как callbacks, futures, и async/await, так и изнутри -- как всё это устроено. Более того, Котлин код можно компилировать под JVM и запускать бок-обок с Java кодом. Несмотря на то, что в Java не предполагается ничего для работы с асинхронностью на уровне языка, а все решения сосередоточены в библиотеках и подразумевают превращение любой нетривиальной асинхронной бизнес-логики в месиво замыкаканий и вызовов различных комбинаторов, корутины Котлина можно интегрировать и с асинхронных кодом на Java, что мы увидим на примерах.
This file contains hidden or 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.experimental.channels.* | |
import kotlinx.coroutines.experimental.* | |
class DownloadQueue { | |
private sealed class Msg { | |
class Request(val name: String) : Msg() { | |
val answer = CompletableDeferred<Unit>() | |
} | |
class Result(val name: String, val error: Throwable? = null) : Msg() | |
} |
This file contains hidden or 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
// Inspired by http://akarnokd.blogspot.ru/2017/09/rxjava-vs-kotlin-coroutines-quick-look.html | |
// Requires Kotlin 1.2.30 or later | |
// Uses kotlinx.coroutines library | |
import kotlinx.coroutines.experimental.* | |
import kotlin.system.* | |
suspend fun f1(i: Int): Int { | |
println("f1 attempt $i") | |
delay(if (i != 3) 2000 else 200) |
This file contains hidden or 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.experimental.DefaultDispatcher | |
import kotlinx.coroutines.experimental.channels.ReceiveChannel | |
import kotlinx.coroutines.experimental.channels.consumeEach | |
import kotlinx.coroutines.experimental.channels.produce | |
import kotlinx.coroutines.experimental.delay | |
import kotlinx.coroutines.experimental.runBlocking | |
import kotlin.coroutines.experimental.CoroutineContext | |
fun <T> ReceiveChannel<T>.debounce( | |
wait: Long = 300, |
In markdown format empty line is not placed after the code block. For example:
this block
should be followed by an empty line in markdown mode, while it is not (it formats correctly in wiki mode)
This file contains hidden or 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 java.util.concurrent.atomic.AtomicReference | |
private val cache = object : ClassValue<AtomicReference<Any?>>() { | |
override fun computeValue(type: Class<*>) = AtomicReference<Any?>() | |
} | |
/** | |
* Caches the given expression statically. | |
* | |
* Use it like this: |
This file contains hidden or 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
// https://akarnokd.blogspot.ru/2017/09/rxjava-vs-kotlin-coroutines-quick-look.html | |
// Abstraction | |
import kotlinx.coroutines.experimental.* | |
suspend fun f1(i: Int): Int { | |
Thread.sleep(if (i != 2) 2000L else 200L) | |
return 1 | |
} | |
suspend fun f2(i: Int): Int { |
This file contains hidden or 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
// https://akarnokd.blogspot.ru/2017/09/rxjava-vs-kotlin-coroutines-quick-look.html | |
// Refactoring | |
import kotlinx.coroutines.experimental.* | |
suspend fun f1(i: Int): Int { | |
Thread.sleep(if (i != 2) 2000L else 200L) | |
return 1 | |
} | |
suspend fun f2(i: Int): Int { |
This file contains hidden or 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
// https://akarnokd.blogspot.ru/2017/09/rxjava-vs-kotlin-coroutines-quick-look.html | |
import kotlinx.coroutines.experimental.* | |
suspend fun f1(i: Int): Int { | |
Thread.sleep(if (i != 2) 2000L else 200L) | |
return 1 | |
} | |
suspend fun f2(i: Int): Int { | |
Thread.sleep(if (i != 2) 2000L else 200L) |
This file contains hidden or 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.experimental.runBlocking | |
import okhttp3.* | |
import java.io.IOException | |
import kotlin.coroutines.experimental.suspendCoroutine | |
fun main(args: Array<String>) { | |
val http = OkHttpClient.Builder().build() | |
val appid = "mock" | |
val secret = "mock" | |
val code = "mock" |