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)
// 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 { |
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: |
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)
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, |
Котлин революционизирует асинхронное программирование. В версии 1.1 в языке появились корутины -- это свежий, отличных от других языков подход к проблеме написания асинхронного кода. Мы посмотрим на этот механизм как сверху -- чем он отличается от традиционных подходов таких как callbacks, futures, и async/await, так и изнутри -- как всё это устроено. Более того, Котлин код можно компилировать под JVM и запускать бок-обок с Java кодом. Несмотря на то, что в Java не предполагается ничего для работы с асинхронностью на уровне языка, а все решения сосередоточены в библиотеках и подразумевают превращение любой нетривиальной асинхронной бизнес-логики в месиво замыкаканий и вызовов различных комбинаторов, корутины Котлина можно интегрировать и с асинхронных кодом на Java, что мы увидим на примерах.
// 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) |
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() | |
} |
import kotlinx.coroutines.experimental.* | |
import kotlinx.coroutines.experimental.channels.* | |
import kotlinx.coroutines.experimental.selects.* | |
import java.util.concurrent.* | |
// operator | |
fun <T> ReceiveChannel<T>.distinctInTimeWindow(time: Long, unit: TimeUnit): ReceiveChannel<T> = produce { | |
require(time > 0) | |
consume { | |
val source = this@distinctInTimeWindow |
import java.util.concurrent.* | |
fun main(args: Array<String>) { | |
class DomainSpecificException : RuntimeException() | |
val cf1 = CompletableFuture<Int>() | |
val cf2 = CompletableFuture<Int>() | |
val res = cf1.thenCompose { cf2 } | |
cf1.whenComplete { _, err -> println("cf1: Completed with error = $err") } |
import java.util.stream.Stream | |
abstract class NodeScaffold<THIS : NodeScaffold<THIS>> { | |
private val children: List<THIS>? = null | |
fun children(): Stream<THIS> { | |
return children!!.stream() | |
} |